Date & Time (java.time)
Tarih ve saatle çalışmak, neredeyse her uygulamada gereklidir: kayıt zamanı, doğum tarihi, randevu, zaman damgası, geri sayım. Java 8'e kadar bu, hatalı ve sinir bozucu Date/Calendar sınıflarıyla yapılırdı. Java 8, ja…
Date & Time (java.time)
Tarih ve saatle çalışmak, neredeyse her uygulamada gereklidir: kayıt zamanı, doğum tarihi, randevu,
zaman damgası, geri sayım. Java 8'e kadar bu, hatalı ve sinir bozucu Date/Calendar sınıflarıyla
yapılırdı. Java 8, java.time paketini getirdi: değişmez, açık ve doğru tasarlanmış modern bir
tarih/saat API'si. Bu konu, tarih/saatle güvenle çalışmayı baştan sona ele alır.
Neden eski Date/Calendar değil?
Eski API'nin sorunları efsanevidir: Date değişebilir (mutable — thread-safe değil),
aylar 0'dan başlar (Ocak = 0!), yıl 1900'den sayılır, SimpleDateFormat thread-safe değildir.
java.time bunların hepsini çözer: değişmez, açık adlandırma, mantıklı değerler.
Temel tipler
| Tip | Ne tutar | Örnek |
|---|---|---|
LocalDate | Yalnızca tarih | 2026-06-23 |
LocalTime | Yalnızca saat | 14:30 |
LocalDateTime | Tarih + saat (bölgesiz) | 2026-06-23T14:30 |
ZonedDateTime | Tarih + saat + bölge | ...Europe/Istanbul |
Instant | Zaman çizgisinde bir an (UTC) | epoch tabanlı |
Period | Tarih farkı (yıl/ay/gün) | 30 yıl 1 ay |
Duration | Zaman farkı (saat/dk/sn) | 8 saat 30 dk |
Oluşturma ve aritmetik
LocalDate t = LocalDate.of(2026, Month.JUNE, 23); // sabit LocalDate bugun = LocalDate.now(); // şu an t.plusDays(10); t.minusMonths(2); t.plusYears(1); // YENİ nesne (immutable!) t.getDayOfWeek(); // gün adı dun.isBefore(t); t.isAfter(dun); // karşılaştırma
Değişmezlik: Tüm
java.timetipleri değişmezdir;plus/minusorijinali değiştirmez, yeni bir nesne döndürür.t.plusDays(10);tek başına bir işe yaramaz — sonucu kullanmalısın.
Örnek 1 (./Ornek1.java) temel tipleri, aritmetiği, Period/Duration ve ChronoUnit.between ile
fark hesabını gösterir.
Biçimlendirme ve ayrıştırma
DateTimeFormatter, tarih/saat ↔ String dönüşümünü yapar:
DateTimeFormatter f = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm"); dt.format(f); // tarih -> "23.06.2026 14:30" LocalDateTime.parse("15.08.2026 09:45", f); // String -> tarih
Desen harfleri: yyyy yıl, MM ay (sayı), MMMM ay (ad), dd gün, HH saat (24'lük), mm
dakika, EEEE gün adı. Locale ile dile özgü (Türkçe ay/gün adları) biçim alınır. Örnek 2
(./Ornek2.java) biçimlendirme ve ayrıştırmayı gösterir.
Thread-safety: Eski
SimpleDateFormat'ın aksine,DateTimeFormatterthread-safe'dir; bir kez oluşturup paylaşabilirsin.
Zaman dilimleri ve Instant
Küresel uygulamalarda zaman dilimi kritiktir:
ZonedDateTime ist = ZonedDateTime.of(dt, ZoneId.of("Europe/Istanbul")); ZonedDateTime ny = ist.withZoneSameInstant(ZoneId.of("America/New_York")); // aynı an, farklı yerel saat Instant an = ist.toInstant(); // mutlak an (UTC, epoch)
ZonedDateTime: Belirli bir bölgedeki tarih/saat (yaz saati dahil).Instant: Zaman çizgisindeki mutlak bir an (UTC, epoch'tan beri). Loglar, zaman damgaları, makineler arası iletişim için.
Örnek 2 İstanbul ↔ New York dönüşümünü ve Instant'ı gösterir.
Altın kural: Zamanı UTC olarak sakla/ilet (
Instant), yalnızca kullanıcıya gösterirken yerel bölgeye çevir. Bu, zaman dilimi ve yaz saati hatalarını önler.
Spring/JPA ile
Modern Java/Spring java.time tiplerini doğrudan destekler: JPA @Entity alanları LocalDate/
LocalDateTime/Instant olabilir; Jackson bunları JSON'a (ISO-8601) çevirir; veritabanı sürücüleri
eşler. Yani eski Date'e dönmene gerek yoktur.
Özet
Modern java.time API'sini öğrendik: neden eski Date/Calendar'dan üstün olduğunu; temel tipleri
(LocalDate/Time/DateTime), değişmez aritmetiği, Period/Duration (Örnek 1); biçimlendirme/
ayrıştırmayı (DateTimeFormatter) ve zaman dilimlerini (ZonedDateTime/Instant; Örnek 2) gördük;
"UTC sakla, yerelde göster" kuralını ve Spring/JPA entegrasyonunu ele aldık. Bununla temel/kavramsal
derin konular batch'i tamamlandı.
▶ Kod Örnekleri(2)
Ornek1
çalıştırılabilir1// Ornek1: java.time temelleri — LocalDate, LocalTime, LocalDateTime, Period, Duration.
2// Çalıştırma: java Ornek1.java
3import java.time.Duration;
4import java.time.LocalDate;
5import java.time.LocalDateTime;
6import java.time.LocalTime;
7import java.time.Month;
8import java.time.Period;
9import java.time.temporal.ChronoUnit;
10
11public class Ornek1 {
12
13 public static void main(String[] args) {
14 // LocalDate: yalnızca tarih (saat yok). of(...) ile sabit, now() ile bugün.
15 LocalDate tarih = LocalDate.of(2026, Month.JUNE, 23);
16 System.out.println("Tarih: " + tarih + " | gün: " + tarih.getDayOfWeek());
17
18 // Aritmetik: DEĞİŞMEZ (immutable) -> her işlem YENİ nesne döndürür.
19 System.out.println("10 gün sonra : " + tarih.plusDays(10));
20 System.out.println("2 ay önce : " + tarih.minusMonths(2));
21 System.out.println("Gelecek yıl : " + tarih.plusYears(1));
22
23 // LocalTime ve LocalDateTime
24 LocalTime saat = LocalTime.of(14, 30, 0);
25 LocalDateTime tam = LocalDateTime.of(tarih, saat);
26 System.out.println("\nSaat: " + saat + " | Tam: " + tam);
27
28 // Karşılaştırma
29 LocalDate dun = tarih.minusDays(1);
30 System.out.println("\ndün, bugünden önce mi? " + dun.isBefore(tarih));
31
32 // Period: TARİH farkı (yıl/ay/gün). Duration: ZAMAN farkı (saat/dakika/saniye).
33 LocalDate dogum = LocalDate.of(1995, 5, 20);
34 Period yas = Period.between(dogum, tarih);
35 System.out.println("\nYaş: " + yas.getYears() + " yıl " + yas.getMonths() + " ay " + yas.getDays() + " gün");
36 System.out.println("Toplam gün (ChronoUnit): " + ChronoUnit.DAYS.between(dogum, tarih));
37
38 Duration sure = Duration.between(LocalTime.of(9, 0), LocalTime.of(17, 30));
39 System.out.println("Mesai süresi: " + sure.toHours() + " saat " + (sure.toMinutes() % 60) + " dk");
40
41 System.out.println("""
42
43 --- java.time temelleri (Java 8+) ---
44 LocalDate (tarih), LocalTime (saat), LocalDateTime (ikisi) — hepsi DEĞİŞMEZ ve thread-safe.
45 of(...) sabit oluşturur; now() şu anı verir; plus/minus YENİ nesne döndürür (orijinali değişmez).
46 Period: tarih farkı (yıl/ay/gün). Duration: zaman farkı (saat/dk/sn). ChronoUnit.between: tek birimde fark.
47 Eski Date/Calendar'a göre: değişmez, açık, hatasız. (Date değişebilir ve thread-safe değildi.)""");
48 }
49}Ornek2
çalıştırılabilir1// Ornek2: Biçimlendirme/ayrıştırma (DateTimeFormatter) ve zaman dilimleri (ZonedDateTime, Instant).
2// Çalıştırma: java Ornek2.java
3import java.time.Instant;
4import java.time.LocalDateTime;
5import java.time.ZoneId;
6import java.time.ZonedDateTime;
7import java.time.format.DateTimeFormatter;
8import java.util.Locale;
9
10public class Ornek2 {
11
12 public static void main(String[] args) {
13 LocalDateTime dt = LocalDateTime.of(2026, 6, 23, 14, 30, 0);
14
15 // BİÇİMLENDİRME: tarih/saat -> okunabilir String (DateTimeFormatter).
16 DateTimeFormatter trFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
17 System.out.println("Biçimli (tr): " + dt.format(trFormat));
18 DateTimeFormatter uzun = DateTimeFormatter.ofPattern("d MMMM yyyy, EEEE", new Locale("tr"));
19 System.out.println("Uzun (tr) : " + dt.format(uzun));
20 System.out.println("ISO standart: " + dt.format(DateTimeFormatter.ISO_DATE_TIME));
21
22 // AYRIŞTIRMA: String -> tarih/saat (parse). Format eşleşmeli.
23 LocalDateTime ayristirilan = LocalDateTime.parse("15.08.2026 09:45", trFormat);
24 System.out.println("\nAyrıştırılan: " + ayristirilan);
25
26 // ZAMAN DİLİMLERİ: ZonedDateTime belirli bir bölgedeki zamanı temsil eder.
27 ZonedDateTime istanbul = ZonedDateTime.of(dt, ZoneId.of("Europe/Istanbul"));
28 ZonedDateTime newYork = istanbul.withZoneSameInstant(ZoneId.of("America/New_York"));
29 System.out.println("\nİstanbul: " + istanbul.format(trFormat) + " " + istanbul.getZone());
30 System.out.println("New York: " + newYork.format(trFormat) + " " + newYork.getZone()
31 + " (AYNI an, farklı yerel saat)");
32
33 // Instant: zaman çizgisindeki bir an (UTC, epoch'tan beri). Makineler/zaman damgaları için.
34 Instant an = istanbul.toInstant();
35 System.out.println("\nInstant (UTC): " + an);
36 System.out.println("Epoch saniye : " + an.getEpochSecond());
37
38 System.out.println("""
39
40 --- Biçimlendirme, ayrıştırma ve zaman dilimleri ---
41 DateTimeFormatter: ofPattern(\"dd.MM.yyyy HH:mm\") ile biçimlendir (format) ve ayrıştır (parse).
42 Desen harfleri: yyyy yıl, MM ay(sayı), MMMM ay(ad), dd gün, HH saat(24), mm dk, EEEE gün adı.
43 ZonedDateTime: belirli bir BÖLGEDEKİ tarih/saat (ZoneId). withZoneSameInstant: aynı anı başka bölgede göster.
44 Instant: zaman çizgisindeki mutlak bir an (UTC, epoch tabanlı) — zaman damgaları/loglar için.
45 Kural: depolama/iletişimde UTC (Instant) sakla; KULLANICIYA gösterirken yerel bölgeye çevir.""");
46 }
47}