Zaman ve Saat Dilimleri — Havale Hangi Güne Yazılır?
Önce şunu oku: BigDecimal — Parada Kuruş Kaybetmemek
30 saniyede özet
Bir an tek bir noktadır ama her şehrin duvar saati onu başka gösterir. Anı Instant olarak saklarsın, saat dilimini yalnızca gösterirken uygularsın. Ofset bir sabit değildir: yaz saatiyle değişir.
İstanbul’dan Londra’ya uçtun ve indiğinde saatini üç saat geri aldın. Saatin değişti ama sen aynı andasın.
Kodda da bir an ile o anı gösteren duvar saati ayrı şeylerdir. Bunları karıştırmak, bankada havalenin yanlış güne yazılması demektir.
Adım adım oku
- Bir havale gönderildi: zaman çizgisinde tek bir an.
- İstanbul'daki duvar saati o anda 23:10 gösteriyor.
- Aynı anda Berlin'de 21:10, New York'ta 15:10.
- Üç farklı saat, ama hepsi aynı an.
-
Bayt: Gün sonu raporu tutmuyor! Dünkü toplamda bugünün havaleleri var.
-
Sen: Her sunucu saati kendi yazıyor, değil mi?
-
Bayt: Evet... ve hangi şehrin saati olduğunu yazmıyor.
-
Bayt: O zaman önce 'an' ile 'saat' arasındaki farkı ayıralım.
Bir an, birçok saat
| Tip | Ne tutar | Örnek |
|---|---|---|
Instant | Zaman çizgisinde bir an | Havalenin gerçekleştiği an |
LocalDate | Saat dilimi olmayan bir tarih | Doğum günü |
LocalDateTime | Saat dilimi olmayan tarih ve saat | Takvimdeki bir not |
ZonedDateTime | Tarih, saat ve bölgenin kuralları | Berlin’de 10:00’da toplantı |
Instant bir anı UTCDünyanın ortak saat referansı. Yaz saati yoktur; her saat dilimi UTC'ye göre bir ofsetle tanımlanır, örneğin İstanbul +03:00.Java'da Instant bir anı UTC çizgisinde tutar. Loglar ve kayıtlar UTC'de tutulursa farklı ülkelerdeki sunucular aynı dili konuşur.Sözlükte gör → çizgisinde tutar ve kimseye göre değişmez. LocalDateTime ise “saat 22:20” der ama hangi şehirde olduğunu söylemez; bu yüzden bir an değildir.
Instant at = Instant.now();ZonedDateTime istanbul = at.atZone(ZoneId.of("Europe/Istanbul"));Kafam karıştı, daha basit anlat
Olayın ne zaman olduğunu kaydediyorsan Instant. Birine saat gösteriyorsan, onun bölgesiyle ZonedDateTime.
Bir havalenin gerçekleştiği anı kaydetmek için hangi tip kullanılır?
Her ihtiyaca uygun java.time tipini seç.
Saat kayınca: yaz saati
Avrupa ve ABD yılda iki kez saatleri bir saat oynatır. Buna yaz saatiBazı ülkelerin yılda iki kez saatleri bir saat oynatması. İlkbaharda bir saat hiç yaşanmaz, sonbaharda bir saat iki kez yaşanır.Ofset bu yüzden tarihe göre değişir. Türkiye 2016'dan beri yaz saati uygulamıyor ve yıl boyu +03:00 kullanıyor.Sözlükte gör → denir ve ofseti tarihe göre değiştirir.
Berlin 29 Mart 2026 gecesi saatleri 02:00'dan 03:00'a atlıyor. `ZonedDateTime.of(2026-03-29, 02:30, Europe/Berlin)` ne döner? Cevabı göster
03:30, ofset +02:00. O gece 02:30 Berlin’de hiç yaşanmaz. Java hata vermez; saati boşluğun uzunluğu kadar ileri kaydırır.
Sonbaharda tersi olur: 02:30 iki kez yaşanır. Java varsayılan olarak ilkini seçer; withLaterOffsetAtOverlap() ikincisini verir.
Bu yüzden ofseti koda elle yazmak tehlikelidir. Kuralları bir ZoneIdBir bölgenin saat kurallarının adı, örneğin Europe/Berlin. Hangi tarihte hangi ofsetin geçerli olduğunu bilir; sabit bir ofset değildir.Kurallar IANA tz veritabanından gelir ve JDK güncellemeleriyle yenilenir. ZoneOffset ise yalnızca sabit bir farktır, örneğin +02:00.Sözlükte gör → bilir: Europe/Berlin hangi tarihte hangi ofsette olduğunu kendisi söyler.
Kafam karıştı, daha basit anlat
Bazı geceler bir saat kaybolur, bazı geceler bir saat iki kez yaşanır. Bunu sen hesaplama; şehrin adını ver, Java hesaplasın.
İstanbul neden kolay görünüyor?· istersen atla
Türkiye 2016’dan beri yıl boyu +03:00 kullanıyor. Ama karşı taraftaki Berlin ya da New York sunucusu yaz saatine geçiyor; senin kodun yine de kurallara uymak zorunda.
Berlin 29 Mart 2026 gecesi saatleri 02:00'dan 03:00'a atlıyor. Bu kod ne yazdırır?
t = 2026-03-28T12:00 Europe/Berlin. t.plus(Duration.ofHours(24)) ile t.plus(Period.ofDays(1)) ne verir? (O gece Berlin yaz saatine geçiyor.)
Saati test edilebilir yapmak
Instant.now() her çağrıda başka bir değer döner. “Gece yarısından sonra gelen havale ertesi güne yazılır” kuralını test etmek için saati durdurabilmen gerekir.
Çözüm, saati bir Clock olarak dışarıdan vermektir. Üretimde gerçek saat, testte sabit bir an kullanılır.
Clock clock = Clock.fixed(Instant.parse("2026-01-15T21:05:00Z"), ZoneId.of("Europe/Istanbul"));BusinessDay day = new BusinessDayResolver(clock).today(); // 2026-01-16Gece yarısı kuralını test etmek için iş kodunda saat nasıl okunmalı?
Kendin gör
Beş havale İstanbul, Berlin ve New York’taki sunuculardan geliyor. Sunucuların zamanı nasıl sakladığını seç ve gün sonu raporuna bak.
Gün sonu: havale hangi güne yazılır?
Tohum 1Oynat ya da adımla.
Şu an ne oldu?
İstanbul'da gün sonu yaklaşıyor
Beş havale geliyor. Her biri, İstanbul saatiyle gerçekleştiği güne yazılmalı. Gün gece yarısı biter.
Görevler0/3
Saat dilimi kaybolunca iki havalenin yanlış güne yazıldığını göraçık
İpucu
Her sunucunun kendi duvar saatini sakladığı seçeneği sonuna kadar oynat.
Kışın doğru çalışan sabit ofsetin bozulduğu haftayı bulaçık
İpucu
Ofseti kim, hangi mevsimde yazdı?
Mart haftasında bile raporu doğru çıkaraçık
İpucu
Mevsimden etkilenmeyen tek değer hangisi?
Olay günlüğü (0)
Henüz olay yok. Oynat veya adımla.
- Varsayılanı oynat. Saat dilimi kaybolunca iki havale yanlış güne yazılıyor ve sıralama bozuluyor.
- Sabit ofseti dene. Ocak’ta her şey doğru.
- Aynı seçenekte haftayı Mart yap. New York yaz saatine geçti; bir havale kayıyor.
- Instant’a geç. Mevsim ne olursa olsun rapor doğru.
Simülatörde sabit ofset (New York -05:00) Ocak'ta doğru çalıştı, Mart'ta bir havaleyi yanlış güne yazdı. Neden?
Tuzaklar
Sunucunun varsayılan dilimine güvenmek. LocalDateTime.now() sunucunun ayarına bağlıdır; aynı kod başka bir makinede başka sonuç verir.
Bir günü 24 saat sanmak. Yaz saati gecesinde plus(Duration.ofHours(24)) duvar saatini kaydırır. Takvim günü için Period.ofDays(1) kullanılır.
Eski Date ve SimpleDateFormat. SimpleDateFormat thread-safe değildir; static bir alanda paylaşılınca tarihler karışır. DateTimeFormatter değişmezdir ve paylaşılabilir.
Bu sınıf farklı ülkelerdeki sunucularda çalışıyor ve yük altında. Sorunlu satırları işaretle.
Derinleş · Gün sonu: havaleyi doğru iş gününe yazmak 4 dosya · ~57 satır · ilk okumada atlayabilirsin
Kendini sına
Önce hızlı bir ısınma: puan yok, kayıt yok. Sonra asıl sorular.
LocalDateTime zaman çizgisinde tek bir anı gösterir.
Farklı ülkelerdeki servislerin yazdığı havale zamanlarını PostgreSQL'de nasıl saklarsın?
Aklında kalacak üç şey
- 1 Instant bir andır, LocalDateTime ise saat dilimi olmayan bir duvar saati. Bir şeyin ne zaman olduğunu kaydederken Instant saklanır.
- 2 Ofset tarihe göre değişir. Yaz saatinde bazı saatler hiç yaşanmaz, bazıları iki kez yaşanır; bu kuralları ZoneId bilir, elle yazılan ofset bilmez.
- 3 Kod saati doğrudan değil, enjekte edilen bir Clock'tan okursa testler istenen her ana sabitlenebilir.
3 kart sonraki derste seni bekliyor