Date Nesnesi: Zaman İçinde Bir An
JavaScript'te Date, zaman içindeki tek bir anı temsil eder — aslında içerde tuttuğu şey, 1 Ocak 1970 UTC'den (yani "Unix epoch"tan) bu yana geçen milisaniye sayısından ibarettir. Yıl, ay, gün, saat dilimi, biçimlendirme… geri kalan her şey bu sayının üzerine giydirilmiş birer görünümden ibaret.
now.getTime() sana ham milisaniye değerini verir. Bir Date nesnesinin yaptığı her şey — karşılaştırma, gün ekleme, formatlama — aslında bu sayıyı değiştirip sonra yeniden yorumlamaktan ibarettir.
Bu modeli aklında tut. Bir Date nesnesi "Paris'te 14 Mart" değildir. Evrensel bir andır; hangi saat diliminden baktığına göre Paris'te 14 Mart ya da Los Angeles'ta 13 Mart olarak gösterilebilir.
JavaScript'te Date nesnesi oluşturma
Bir Date oluşturmanın dört temel yolu vardır:
Dikkat etmeniz gereken iki nokta var:
- Parçalı constructor 0'dan başlayan ay indeksi kullanır.
2değeri Mart'a denk gelir; Ocak ise0'dır. Bu, sürekli bir "bir eksik/bir fazla" (off-by-one) hata kaynağıdır. API'nin geri kalanında da aylar 0'dan başladığı için en azından kendi içinde tutarlı diyebiliriz. new Date("2026-03-14")(saat bilgisi olmadan) UTC gece yarısı olarak parse edilir.new Date("2026-03-14T09:30")ise (sonundaZyoksa) yerel saat olarak parse edilir. Bu simetrisizlik klasik bir tuzaktır.
"Şu anı" bir sayı olarak almak istediğinizde Date.now() tercih edin; nesne oluşturma maliyetinden kurtulursunuz:
Date.now(), geçen süreyi ölçmek, zaman aşımı kontrolü yapmak ya da takvim hesabına gerek duymadığın her durumda tam aradığın araçtır.
Bir tarihin parçalarına erişmek
Elinde bir Date nesnesi olduğunda, bileşenlerine getter metotlarıyla ulaşırsın. Her birinin iki versiyonu var: biri yerel saate, diğeri UTC'ye göre çalışır.
Yerel saat üzerinden çalışan metotlar, kodu kimin makinesi çalıştırıyorsa ona göre sonuç verir. Tarihleri farklı kullanıcılar ve sunucular arasında saklıyor ya da karşılaştırıyorsan, açıkça UTC tercih et; yoksa hayali hatalarla uğraşırsın. Pratik kural: veritabanına ya da log'a yazılacak her şey için UTC getter'larını kullan; kullanıcıya göstereceğin şeyler için ise yerel getter'ları tercih et.
getYear() kullanma. Bu metot year - 1900 değerini döndüren, sadece geriye dönük uyumluluk için duran eski (legacy) bir metot. Her zaman getFullYear() kullan.
Tarihi Okunabilir Biçimde Göstermek
Önemsediğin bir şey için date.toString() kullanmaktan kaçın — çıktısı locale'e ve JavaScript motoruna göre değişiyor. Bilmeye değer iki formatlayıcı var.
Makine tarafından okunabilir standart bir string için toISOString() kullan:
Loglama, JSON'a kaydetme ya da ağ üzerinden veri gönderme gibi durumlarda kullanman gereken format budur. Her zaman UTC'dir ve hiçbir belirsizliğe yer bırakmaz.
Kullanıcıya gösterilecek bir tarih metni için ise Intl.DateTimeFormat veya onu sarmalayan toLocale* metotlarını tercih et:
Intl.DateTimeFormat hem dil/bölge ayarlarını hem zaman dilimlerini, hem de isteyebileceğin her alan kombinasyonunu sorunsuzca halleder. ${year}-${month}-${day} gibi elle format kurmaya girişmeden önce buna bir şans ver — bu tür string birleştirmeleri, meşhur "ay bir eksik çıkıyor" hatalarının doğduğu yerdir.
JavaScript'te tarih karşılaştırma
Aynı anı temsil eden iki Date nesnesi === ile eşit değildir — çünkü === değeri değil, nesne kimliğini karşılaştırır. Onun yerine zaman damgalarını (timestamp) karşılaştır:
Karşılaştırma operatörleri tarihlerde doğrudan çalışır, çünkü arka planda sayıya dönüştürme yapılır:
Çıkarma işlemi sana aradaki farkı milisaniye cinsinden verir. Gün sayısına çevirmek için 1000 * 60 * 60 * 24'e böl. İlk seferinde bu sabiti açık açık yazmakta fayda var; zamanla 86_400_000 rakamını görür görmez tanıyacaksın.
Tarih Üzerinde Aritmetik İşlemler
JavaScript'te hazır bir addDays metodu yok. Alışılmış yöntem setDate, setMonth gibi metotları kullanmak — bunlar aralık dışı değerleri kabul eder ve taşmayı doğru şekilde yönetir:
Dikkat edilmesi gereken iki nokta var:
new Date(date)tarihi kopyalar.setDateise nesneyi doğrudan değiştirir (mutate eder), bu yüzden önce mutlaka kopya alın; yoksa çağıranın değerini bozarsınız.- 31 günlük bir ayda
setDate(35)çağırırsanız otomatik olarak bir sonraki aya geçer.setMonth(14)için de aynısı geçerli — yılı ileri alır. Bu davranış, tarih aritmetiğini göründüğünden çok daha kolay hale getiriyor.
Karmaşık şeyler için — iş günleri, tekrarlayan etkinlikler, ay farkını dikkate alan süreler — bir kütüphaneye uzanın (date-fns, Luxon ya da yakında gelecek olan Temporal API). "Birkaç gün ekle" seviyesinin ötesinde kendi takvim mantığınızı yazmaya kalkışmak tam bir bataklık.
Saat Dilimi Gerçeği
Saat dilimleri, tarih hatalarının bir numaralı kaynağıdır. Aklınıza kazımanız gereken kurallar şunlar:
- Bir
Datenesnesi aslında bir UTC anını saklar. Saat dilimi yalnızca parçaları okurken veya formatlarken devreye girer. getHours(),getDate()gibi metotların kullandığı saat dilimi, kodu çalıştıran makinenin yerel saat dilimidir. Sunucu ile tarayıcı çoğu zaman aynı fikirde olmaz.new Date("2026-03-14")(sadece tarih) UTC olarak yorumlanır.new Date("2026-03-14T00:00")(saat var, dilim yok) yerel saat olarak yorumlanır.new Date(2026, 2, 14)(parçalı kullanım) da yereldir.
Görüntüleme için belirli bir saat dilimi gerektiğinde, Intl.DateTimeFormat fonksiyonuna timeZone parametresini verebilirsiniz:
Aynı an, iki farklı görünüm. Date nesnesinin kendisi değişmedi.
Küçük Bir Çalışan Örnek
Şimdi hepsini bir araya getirelim — bir şeyin ne kadar zaman önce yaşandığını formatlayan bir fonksiyon:
Girişte timestamp, çıkışta okunabilir bir metin. Gerçek dünyadaki tarih kodunun %90'ı aslında böyle: iki anı birbirinden çıkar, bir birime böl, yuvarla, biçimlendir.
Özetle Aklında Kalsın
Datenesnesi aslında bir UTC anıdır. Zaman dilimi sadece okurken veya biçimlendirirken devreye girer.- Timestamp için
Date.now(), takvim işleri içinnew Date()kullan. - Kayıt ve log için
toISOString(), kullanıcıya göstermek içinIntl.DateTimeFormat. - Karşılaştırma yaparken
getTime()ya da</>kullan. Sakın===deme. - Aylar 0'dan başlar. Bir de sadece tarih içeren string'lerin parse edilmesi meselesinin tuzağına dikkat.
- Ciddi tarih hesapları için bir kütüphane kullan.
Sırada: URL'ler ve Query String'ler
Tarihler çoğu zaman URL'lerde de karşımıza çıkar — tarih aralığına göre filtreleme, query parametresi olarak geçirilen timestamp'ler vs. URL'leri elle parse etmek ya da oluşturmak, tarih biçimlendirmeyi elle yapmak kadar hataya açık bir iş. Neyse ki standart kütüphanedeki URL nesnesi bu işi temiz bir şekilde hallediyor. Sıradaki konumuz bu.
Sıkça Sorulan Sorular
JavaScript'te bugünün tarihini nasıl alırım?
Argümansız olarak new Date() çağırman yeterli. Bu, constructor'ın çalıştığı anı temsil eden bir Date nesnesi döndürür. Sadece sayısal bir timestamp (1970'ten beri geçen milisaniye) istiyorsan Date.now() kullan — hem daha hızlıdır hem de ortada koca bir nesne oluşturmak zorunda kalmazsın.
JavaScript'te iki tarihi nasıl karşılaştırırım?
Date nesnelerini doğrudan değil, timestamp'lerini karşılaştır. a.getTime() < b.getTime() işe yarar; a < b de çalışır çünkü < operatörü tarihleri otomatik olarak sayıya çevirir. Ama a === b çalışmaz — === nesne kimliğine bakar, yani aynı anı temsil eden iki farklı Date nesnesi asla birbirine eşit sayılmaz.
JavaScript'te tarih nasıl biçimlendirilir?
Kullanıcıya gösterilecek bir şeyse Intl.DateTimeFormat veya date.toLocaleDateString() kullan — yerel ayarları ve zaman dilimlerini düzgünce halleder. Makine tarafından okunacak bir çıktı lazımsa date.toISOString() sana 2026-03-14T09:30:00.000Z gibi standart bir string verir. Veri saklamak için date.toString() kullanma; formatı locale'e göre değişiyor.
JavaScript'te tarihim neden bir gün kayıyor?
Büyük ihtimalle zaman dilimi sorunu. new Date('2026-03-14') bu değeri UTC gece yarısı olarak ayrıştırır, ama date.getDate() sana günü yerel saat diliminde döndürür — ve bu bir önceki gün olabilir. UTC günü için getUTCDate() kullan ya da tarihi baştan yerel saatle new Date(year, month, day) şeklinde oluştur.