Methodology
Tarih ve saat metodolojisi
Naif tarih matematiğinin başarısız olduğu yer — ve her /datetime/ aracının bunu nasıl aştığı.
By Buğra SözeriPublished
Tarih ve saat aritmetiği, herhangi bir büyük kod tabanında en çok denenen ve en çok hata içeren kategorilerden biridir. Tarih & saat kümimizdeki dört araç her biri farklı bir alt sorunu çözer; bu sayfa her birinin arkasındaki matematiği açıklar.
Yaş hesaplayıcı — takvim farkındalıklı ödünç alma
Yıllar-aylar-günler cinsinden yaş, yalnızca “bugün eksi doğum günü bölü 365,25” değildir — bu yaklaşım 4-7 yılda bir gün hata biriktirir. Doğru algoritma takvim ödünç almayı kullanır:
- Yıl farkını hesapla:
şimdi.yıl − doğum.yıl. - Ay farkını hesapla.
şimdi.ay < doğum.ayise, yıl sayısından 12 ay ödünç al. - Gün farkını hesapla.
şimdi.gün < doğum.günise, gerçek bir önceki takvim ayının uzunluğunu kullanarak ay sayısından gün ödünç al.
3. adım naif kodun başarısız olduğu yerdir. “Önceki ay uzunluğu” 30 veya 31 değildir — hangi önceki ay olduğuna bağlıdır (Şubat 28 veya 29, geri kalanlar 30 veya 31). Yaş hesaplayıcımız, artık yıllar dahil her seferinde doğru sayıyı almak için new Date(year, month, 0) (önceki ayın son gününü döndürür) kullanır.
Çalışan örnek
Doğum: 1990-12-31. Bugün: 2026-05-14. Yıl farkı: 36. Ay farkı: −7 (Mayıs eksi Aralık). Bir yıl ödünç al, ay farkı 5 olur. Gün farkı: 14 − 31 = −17. Bir ay ödünç al; önceki ay 30 günlük Nisan, bu nedenle 30 ekle, gün farkı 13 olur. Sonuç: 35 yıl, 4 ay, 13 gün.
Tarih farkı — üç birim, tek payda
Tarih farkı aracı, iki tarih arasındaki boşluğu eş zamanlı olarak gün, hafta ve saat cinsinden bildirir. Matematik basittir:
gün = (b.getTime() − a.getTime()) / 86_400_000hafta = gün / 7 · saat = gün × 24
İncelik, saat dilimi işlemedir. Her iki tarih de çıkarmadan önce UTC gece yarısına normalleştirilir, bu nedenle YGS geçişleri kesirli günlere yol açmaz. Bir ilkbahara geçişi kapsayan tarih farkı, kullanıcıların beklediği gibi tam sayıda gündür.
İş günleri — iki tarih arasında Pazartesi-Cuma
İş günü sayacı, mümkün olan en basit algoritmayı kullanır: iki tarih arasındaki her takvim gününü yürür ve hafta içi Pazartesi-Cuma olduğunda sayacı artırır.
Yılda ~250 hafta içi ve modern V8’de ortalama ~1 µs Date nesne oluşturmayla, bu bir yüzyıl altındaki herhangi bir tarih aralığı için mikrosaniyeler içinde tamamlanır. Kapalı form formül kullanmıyoruz çünkü yalnızca marjinal olarak daha hızlı ve okunması önemli ölçüde daha zor.
Dahil edilmeyen: ulusal tatiller. Tatil kutlaması ülkeye, yıla göre değişir (çoğu tarihe sabitlenmiş ancak anlamlı bir alt küme ay takvimiyle hareket eder veya “ayın N. hafta içi günü” olarak tanımlanır) ve sektöre göre farklılık gösterir. Bunu sorumlu şekilde yapmak için seçilmiş bir veri kümesinden çekmemiz gerekir; iş günü aracı kasıtlı olarak yalnızca hafta içi kalır.
Saat dilimi dönüştürücüsü — IANA tzdata + Intl.DateTimeFormat
Saat dilimleri coğrafi değil siyasi yapılardır ve kuralları değişir. Yaz saati başlangıç tarihleri, yıl boyu YGS deneyleri, ülkelerin yeniden düzenlenmesiyle bölünmeler ve birleşmeler — bunların hepsi her modern işletim sistemiyle birlikte gelen IANA tzdata paketinde yakalanır.
Saat dilimi dönüştürücümüz, tarayıcının yerleşik Intl.DateTimeFormat’u aracılığıyla bu veriye erişir. Asla kendi tzdata’mızı paketlemeyiz. Bu önemlidir çünkü:
- tzdata, ülkeler kuralları değiştirdikçe yılda birkaç kez güncellenir.
- Kendi kopyamızı paketlemek bu veriyi derleme zamanında dondurur.
- İşletim sistemi düzeyinde tzdata, İS satıcısı tarafından bizimkinden daha hızlı bir güvenlik ritmiyle güncellenir.
Duvar saati dönüşüm algoritması
“Europe/Istanbul’da 2026-07-04 tarihinde saat 14:00, America/Los_Angeles’da ne zamandır?”:
- “2026-07-04 tarihinde 14:00”yü UTC zaman damgası olarak ele alın (buna
tahmindeyin). - Intl.DateTimeFormat’a sorun:
tahminanında Europe/Istanbul’un ofseti ne? (UTC+3.) - Ayarlayın: gerçek UTC anı
tahmin − 3 saat. - Bu UTC anını Los_Angeles duvar saatinde işleyin.
Bu, özel durum olmaksızın yarım saat dilimlerini (Hindistan, UTC+5:30) ve 45 dakikalık saat dilimlerini (Nepal, UTC+5:45) işler. Kırılan tek durum “ileri atlama” boşluğudur — 2:00’den 3:00’e atlayan bir bölgede 2:30 mevcut değildir — ancak hesaplayıcı başarısız olmak yerine bir saat kapalı sonucu döndürür, bu da yine de faydalı bilgidir.
ISO 8601 varsayılanı
Kullanıcı arayüzündeki tüm tarih girdileri ISO 8601 biçimini kullanır (YYYY-MM-DD). Dahili olarak üretilen tüm Date nesneleri sınırda saat dilimi bilgisi taşımaz ve yalnızca saat dilimi dönüştürücüsüne geçildiğinde saat dilimi farkındalığı kazanır. Intl.DateTimeFormatçıktısı kullanıcının tarayıcı dilinde yerel ayar farkındadır; temel veri, depolama ve serileştirme için her zaman ISO 8601’dir.
Frequently asked questions
- Neden dayjs veya date-fns gibi bir tarih kütüphanesi kullanmıyorsunuz?
- İçeride, bundan yararlanan parçalar için kullanıyoruz — ancak /lib/datetime/ içindeki her görünür fonksiyon ilkellerden yazılmıştır. Tarih kütüphaneleri boyut karşılığında kolaylık sağlar ve matematiğimiz bağımlılığın buna değmeyecek kadar basit (ve kararlı).
- Saat dilimi dönüştürücüsü geçmiş tarihleri işliyor mu?
- IANA tzdata kapsamı dahilinde, evet. IANA, çoğu bölge için yaklaşık 1970'e, bir alt küme için daha öncesine ait YGS geçiş kurallarını içerir. 1970 öncesi tarihler için döndürülen ofset, tarihsel olarak hatalı olabilecek bölgenin modern ofsetidir. Saat dilimi dönüştürücüsünü soy araştırması için kullanmayın.
Related
- Yaş hesaplayıcı
- Tarih farkı
- İş günleri
- Saat dilimi dönüştürücü
- Toplantı planlayıcı
- Unix zaman damgası dönüştürücü
- Uzak ekipler için saat dilimi rehberi
- Vize başvurularında tarih farkı
- Faturalandırma için iş günleri
- YGS program değişiklikleri (veri)
- Sözlük: UTC
- Sözlük: ISO 8601
- Sözlük: Unix zaman damgası
- Sözlük: IANA saat dilimi
Published May 14, 2026