LocalDate, LocalTime ve LocalDateTime: Nedir, Tarihle Çalışma

Yazar: IT Sectr Yayınlanma: 2026-07-13 Okuma süresi: 12 dk

LocalDate, LocalTime ve LocalDateTime, saat dilimine bağlı olmadan tarih ve saat işlemleri sağlayan java.time paketinin ana sınıflarıdır. Oracle belgelerine (Java 17, 2024) göre, bu türler immutable ve thread-safe olarak tasarlanmıştır, bu da onları çok iş parçacıklı uygulamalar için güvenli kılar. Android'de API 26'dan itibaren desugaring yoluyla ve daha eski sürümler için — ThreeTenABP kütüphanesi aracılığıyla kullanılabilir hale geldiler.

Önemli Noktalar

  • LocalDate — saat ve saat dilimi olmadan tarihi (yıl, ay, gün) temsil eden immutable sınıf.
  • LocalTime — tarih ve saat dilimi olmadan zamanı (saat, dakika, saniye, nanosaniye) temsil eden immutable sınıf.
  • LocalDateTime — LocalDate ve LocalTime'ı birleştirerek saat dilimi bağlantısı olmadan hem tarihi hem de saati saklayan sınıf.
  • Her üç sınıf da aritmetik işlemleri destekler — plus ve minus yöntemleriyle gün, ay, saat ekleme ve çıkarma.
  • Android'de bu türler desugaring (API 26+) veya ThreeTenABP kütüphanesi (API < 26) aracılığıyla kullanılabilir.

LocalDate, LocalTime ve LocalDateTime Nedir?

LocalDate — saat ve saat dilimi bilgisi olmadan yıl-ay-gün formatında tarihi temsil eden bir sınıf. Doğum günleri, etkinlik tarihleri veya son kullanma tarihleri gibi verileri saklamak için kullanılır.

LocalDate, -999999999 ile +999999999 aralığında yıl, 1 ile 12 arasında ay ve artık yılları dikkate alarak ayın gününü saklar. Sınıf tamamen immutable'dır — her işlem yeni bir nesne döndürür.

LocalTime günün saatini temsil eder: saat, dakika, saniye ve nanosaniye. Maksimum hassasiyet nanosaniyeye kadardır. LocalTime, tarih veya saat dilimi bilgisi içermez, bu da onu mağaza açılış saatlerini veya işlem sürelerini saklamak için kullanışlı hale getirir.

LocalDateTime LocalDate ve LocalTime'ı tek bir nesnede birleştirir. Hem tarihi hem de saati saklamanız gerektiğinde ancak saat dilimi bağlantısı gerekmediğinde en sık kullanılan türdür. Örneğin, yerel formatta bir konserin tarihi ve saati.

Oracle Java Belgelerine (2024) göre, her üç sınıf da Joda-Time kütüphanesindeki fikirlere dayanarak tasarlanmıştır, ancak geliştirilmiş mimari ve standart kütüphaneye tam entegrasyon ile.

java.time Paketi Nasıl Çalışır?

java.time paketi, Java 8'de eski Date, Calendar ve SimpleDateFormat sınıflarının yerine geçmek üzere tanıtıldı. Mimarisi, immutable nesneler ve fluent arayüz ilkeleri üzerine inşa edilmiştir.

Önemli bir özellik — tüm ana sınıflar value-based'dır. Bu, örneklerinin referansa göre değil, değere göre karşılaştırıldığı ve miras alınamayacağı anlamına gelir. İki nesneyi karşılaştırmak için == operatörünü değil, equals yöntemini kullanın.

Paket birkaç kategoriye ayrılmıştır. Saat dilimi olmayan türler — LocalDate, LocalTime, LocalDateTime — yerel tarihler ve saatler için kullanılır. Saat dilimi olan türler — ZonedDateTime, OffsetDateTime, OffsetTime — ofset veya bölge bilgisi ekler. Anlık türler — Instant — UTC cinsinden zaman çizgisi üzerinde bir noktayı temsil eder.

Bu ayrım, eski API'de bulunan bir sorunu çözer: geliştirici, bir Date nesnesinin saat dilimi bilgisi içerip içermediğini asla bilemezdi. java.time'da her tür, anlamını açıkça bildirir.

LocalDate: Tarihle Çalışma

LocalDate sınıfı, tarih oluşturma, okuma ve değiştirme için birçok yöntem sağlar. Geçerli tarih, statik yöntem now() ile alınabilir. Belirli bir tarih — of(int year, int month, int dayOfMonth) yöntemiyle alınabilir.

Tarih bileşenlerini okumak için getter'lar kullanılır: getYear(), getMonthValue(), getDayOfMonth(), getDayOfWeek(), getDayOfYear(). getMonth() yöntemi Month enum'unu, getDayOfWeek() ise DayOfWeek enum'unu döndürür.

LocalDate tarih kontrolünü destekler. isBefore(), isAfter() ve isEqual() yöntemleri tarihleri karşılaştırmaya olanak tanır. isLeapYear() yöntemi yılın artık yıl olup olmadığını kontrol eder. lengthOfMonth() yöntemi ay içindeki gün sayısını, lengthOfYear() ise yıl içindeki gün sayısını döndürür.

Değişiklik için withYear(), withMonth(), withDayOfMonth() yöntemleri kullanılır; bunlar değiştirilen bileşenle yeni bir nesne döndürür. plusDays(), minusMonths() ve benzeri yöntemler tarih aritmetiği yapar.

LocalTime: Zamanla Çalışma

LocalTime nanosaniye hassasiyetinde günün saatini temsil eder. Standart biçim ISO-8601'dir (HH:mm:ss.nnnnnnnnn). Minimum değer 00:00, maksimum değer 23:59:59.999999999'dur.

Bir LocalTime nesnesi, geçerli saat için now(), of(int hour, int minute), of(int hour, int minute, int second) veya of(int hour, int minute, int second, int nanoOfSecond) ile oluşturulabilir. parse(CharSequence text) yöntemi, ISO-8601 biçimindeki bir dizeyi ayrıştırır.

Getter'lar şunları içerir: getHour(), getMinute(), getSecond(), getNano(). toSecondOfDay() yöntemi günün başlangıcından itibaren saniye sayısını döndürür ve toNanoOfDay() nanosaniyeyi döndürür. Bu, tek bir gün içindeki süreyi hesaplamak için kullanışlıdır.

LocalTime, LocalDate ile aynı karşılaştırma ve değişiklik işlemlerini destekler: plusHours(), minusMinutes(), withHour(), withMinute(). isBefore() ve isAfter() yöntemleri, zamanın bir gün içinde döngüsel olduğunu dikkate alarak çalışır.

LocalDateTime: Tarih ve Zaman Birleşimi

LocalDateTime LocalDate ve LocalTime'ın yeteneklerini tek bir sınıfta birleştirir. Hem tarihi hem de saati saklar, ancak saat dilimi olmadan. Bu en esnek yerel türdür, ancak dağıtık sistemlerde kullanılırken dikkat gerektirir.

LocalDateTime, statik yöntemler now(), of(LocalDate date, LocalTime time), of(int year, Month month, int dayOfMonth, int hour, int minute) ve aşırı yüklemeleriyle oluşturulabilir. Ayrıca atTime() yöntemiyle LocalDate ve LocalTime birleştirilebilir.

LocalDateTime, ilgili getter'lar aracılığıyla tüm tarih ve zaman alanlarına erişim sağlar: toLocalDate() ve toLocalTime() bireysel bileşenleri döndürür. truncatedTo(TemporalUnit unit) yöntemi, zamanı belirli bir hassasiyete yuvarlamaya olanak tanır — örneğin, dakikalara.

Saat dilimine dönüştürmek için atZone(ZoneId zone) yöntemi kullanılır; bu, ZonedDateTime döndürür. LocalDateTime'a saat dilimi eklemenin tek yolu budur.

Tarih ve Zaman Nesneleri Nasıl Oluşturulur?

Her üç sınıf da statik fabrika yöntemleri aracılığıyla birleşik bir oluşturma deseni kullanır. Sınıf yapıcıları private olarak bildirilmiştir — new kullanarak doğrudan nesne oluşturulamaz.

Ana oluşturma yöntemleri:

  • now() — sistem saatinden geçerli tarih/saat
  • of(...) — bileşenlerden (yıl, ay, gün vb.)
  • parse(String) — ISO-8601 biçimindeki bir dizeden
  • from(TemporalAccessor) — başka bir temporal nesneden

of yönteminin birçok aşırı yüklemesi vardır. LocalDate için yıl, ay ve gün gerekir. LocalTime için — saat ve dakika (isteğe bağlı olarak saniye ve nanosaniye). LocalDateTime için — yıl, ay, gün, saat, dakika. Ay, int (1-12) veya Month enum'u olarak iletilebilir.

kotlin
val today = LocalDate.now()
val specificDate = LocalDate.of(2026, Month.JULY, 21)
val parsedDate = LocalDate.parse("2026-07-21")

val currentTime = LocalTime.now()
val lunchTime = LocalTime.of(13, 30, 0)
val parsedTime = LocalTime.parse("13:30:00")

val now = LocalDateTime.now()
val meeting = LocalDateTime.of(2026, 7, 21, 15, 0)

Türler Arası Dönüşüm

java.time sınıfları, birbirleri arasında uygun dönüşüm için tasarlanmıştır. LocalDate, atTime(LocalTime) veya atStartOfDay() yöntemiyle LocalDateTime'a dönüştürülebilir. LocalTime — atDate(LocalDate) ile.

LocalDateTime, toLocalDate() ile LocalDate'e ve toLocalTime() ile LocalTime'a geri dönüştürülebilir. ZonedDateTime'a dönüştürmek için atZone(ZoneId) yöntemi kullanılır.

java.util.Date'e dönüşüm (eski kodla uyumluluk için), Instant ve bir saat dilimi aracılığıyla bir ara adım gerektirir. Baeldung'a (2024) göre, bu işlem Date.from(instant) aracılığıyla gerçekleştirilir.

kotlin
val date = LocalDate.of(2026, 7, 21)
val dateTime = date.atTime(LocalTime.of(10, 30))

val time = LocalTime.of(14, 0)
val dateTimeFromTime = time.atDate(date)

val extractedDate = dateTime.toLocalDate()
val extractedTime = dateTime.toLocalTime()

val zoned = dateTime.atZone(ZoneId.of("Europe/Moscow"))

Biçimlendirme ve Ayrıştırma

Biçimlendirme ve ayrıştırma için DateTimeFormatter sınıfı kullanılır. Sabitler (ISO_LOCAL_DATE, ISO_LOCAL_TIME, ISO_LOCAL_DATE_TIME) aracılığıyla önceden tanımlanmış biçimler ve desen dizeleri kullanarak özel biçimler oluşturma olanağı sağlar.

Biçimlendirme desenleri semboller kullanır: yyyy — yıl, MM — ay (iki haneli), dd — gün, HH — saat (0-23), mm — dakika, ss — saniye. format() yöntemi, tarih-zaman nesnesi üzerinde veya DateTimeFormatter aracılığıyla çağrılır.

DateTimeFormatter ayrıca, ofLocalizedDate(FormatStyle), ofLocalizedTime(FormatStyle) ve ofLocalizedDateTime(FormatStyle) statik yöntemleri aracılığıyla yerelleştirmeyi de destekler. Mevcut stiller SHORT, MEDIUM, LONG ve FULL'dur.

kotlin
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm")
val formatted = LocalDateTime.now().format(formatter)

val parsed = LocalDate.parse(
    "21.07.2026",
    DateTimeFormatter.ofPattern("dd.MM.yyyy")
)

Tarih-Zaman Nesnelerini Karşılaştırma

Her üç sınıf da Comparable arayüzünü uygulayarak doğal karşılaştırmaya olanak tanır. compareTo() yöntemi, sıraya bağlı olarak negatif, sıfır veya pozitif bir sayı döndürür. isBefore(), isAfter() ve isEqual() yöntemleri boolean döndürür.

LocalDate için karşılaştırma kronolojiktir — daha erken bir tarih daha küçük kabul edilir. LocalTime için — günün saatine göre. LocalDateTime için — önce tarihe, sonra saate göre. Tüm karşılaştırmalar artık yılları ve aylardaki gün sayısını doğru şekilde dikkate alır.

Eski API'den önemli bir fark: LocalDate, LocalTime ve LocalDateTime için equals() değerleri karşılaştırır, referansları değil. Bu, aynı alanlara sahip iki nesnenin farklı örnekler olsalar bile eşit olacağı anlamına gelir.

kotlin
val d1 = LocalDate.of(2026, 7, 21)
val d2 = LocalDate.of(2026, 12, 25)

if (d1.isBefore(d2)) {
    Log.d("Tarih", "d1, d2'den önce")
}

val sortedDates = listOf(d2, d1).sorted()

Tarih ve Zaman Aritmetiği

Her üç sınıf da plus ve minus yöntemleri aracılığıyla aritmetik işlemleri destekler. LocalDate için plusDays(), plusWeeks(), plusMonths(), plusYears() ve karşılık gelen minus yöntemleri mevcuttur. LocalTime, plusHours(), plusMinutes(), plusSeconds(), plusNanos()'u destekler.

LocalDateTime, her iki türden tüm aritmetik işlemleri devralır. LocalDate'in dikkate değer bir özelliği: bir ay eklendiğinde, sonuçlar farklı ay uzunluklarını doğru şekilde işler. Örneğin, 31 Ocak + 1 ay = 28 (artık yılda 29) Şubat.

Daha karmaşık işlemler için Period sınıfı (tarihler için) ve Duration sınıfı (zaman için) bulunur. plus(TemporalAmount) ve minus(TemporalAmount) yöntemleri bu nesneleri kabul eder.

kotlin
val today = LocalDate.now()
val nextWeek = today.plusDays(7)
val nextMonth = today.plusMonths(1)
val lastYear = today.minusYears(1)

val now = LocalTime.now()
val inTwoHours = now.plusHours(2)
val halfHourAgo = now.minusMinutes(30)

Kotlin Kod Örnekleri

Pratik bir örneğe bakalım: iş vardiyası takip uygulaması. Vardiya süresini hesaplamamız ve gece saatine denk gelip gelmediğini belirlememiz gerekiyor. Başlangıç ve bitiş saatleri için LocalTime, tarih için LocalDate ve gece yarısını geçen vardiyaları hesaplamak için LocalDateTime kullanıyoruz.

kotlin
data class Shift(
    val startTime: LocalTime,
    val endTime: LocalTime,
    val date: LocalDate
) {
    fun isOvernight(): Boolean = endTime.isBefore(startTime)

    fun durationInMinutes(): Long {
        val start = LocalDateTime.of(date, startTime)
        val end = LocalDateTime.of(
            if (isOvernight()) date.plusDays(1) else date,
            endTime
        )
        return Duration.between(start, end).toMinutes()
    }
}

İkinci bir örnek — kullanıcının yaşını hesaplama. Doğum tarihi için LocalDate kullanıyoruz ve doğum günü ve ayını dikkate alarak geçerli tarihle karşılaştırıyoruz.

kotlin
fun calculateAge(birthDate: LocalDate): Int {
    val today = LocalDate.now()
    val period = Period.between(birthDate, today)
    return period.years
}

Üçüncü bir örnek — bildirimlerle çalışma. LocalDateTime hatırlatıcıları planlamak için kullanılır. Planlanan zamanın gelip gelmediğini kontrol ederiz.

kotlin
data class Reminder(
    val id: Long,
    val scheduledAt: LocalDateTime
) {
    fun isDue(): Boolean =
        LocalDateTime.now().isAfter(scheduledAt)
}

Android Desteği: API Seviyesi ve Desugaring

java.time için yerleşik destek, Android'de API 26'dan (Android 8.0 Oreo) itibaren ortaya çıktı. Daha eski Android sürümlerine sahip cihazlar için, desugaring — yeni Java API'lerinin desteğini önceki sürümlere ekleyen bir mekanizma — kullanılması gerekir.

Android Gradle Plugin'de Desugaring, build.gradle'daki compileOptions aracılığıyla yapılandırılır. Sadece isCoreLibraryDesugaringEnabled = true olarak ayarlayın ve desugar_jdk_libs kütüphanesini ekleyin. Bundan sonra java.time, 14'ten itibaren tüm API seviyelerinde kullanılabilir hale gelir.

Desugaring kullanamayan projeler için (örneğin, AGP 4.0'ın altındaki eski projeler), ThreeTenABP kütüphanesi bulunur — java.time'ın bir geri uyumluluk sürümü. Aynı sınıfları (LocalDate, LocalTime, LocalDateTime) sağlar, ancak org.threeten.bp paketinde.

groovy
@Suppress("UnstableApiUsage")
android {
    compileOptions {
        isCoreLibraryDesugaringEnabled = true
    }
}

dependencies {
    "coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}

Yaygın Hatalar ve Bunlardan Kaçınma

İlk yaygın hata — saat dilimlerini dikkate almadan dağıtık sistemlerde LocalDateTime kullanmak. Sunucu Europe/Moscow'da ve istemci Asia/Tokyo'da ise, LocalDateTime farklı yorumlanacaktır. Çözüm: genel veriler için Instant veya ZonedDateTime kullanın.

İkinci hata — yanlış dize ayrıştırma. Varsayılan olarak, LocalDate.parse() ISO-8601 biçimini (yyyy-MM-dd) bekler. Dize başka bir biçimdeyse, açıkça bir DateTimeFormatter iletmeniz gerekir. Ayrıca geçersiz girişte uygulamanın çökmemesi için DateTimeParseException'ı işlemelisiniz.

Üçüncü hata — null güvenliğini göz ardı etmek. LocalDate, LocalTime ve LocalDateTime null olabilen nesnelerdir. Kotlin'de açık kontroller veya Elvis operatörüyle nullable türler kullanılması önerilir. Java'da — yöntemleri çağırmadan önce null'u kontrol edin.

Dördüncü hata — LocalDateTime ve ZonedDateTime'ı karıştırmak. LocalDateTime saat dilimi bilgisi içermez. Zamanda mutlak bir anı iletmeniz gerekiyorsa — bölgesel türler kullanın. Yerel saat yeterliyse — yerel türleri kullanın.

Sıkça Sorulan Sorular

Java'da LocalDate ve Date arasındaki fark nedir?

Date, 1970-01-01 UTC'den itibaren milisaniye sayısını saklarken, LocalDate saat dilimi bağlantısı olmadan yıl, ay ve günü saklar. Date değişebilir ve thread-safe değildir, LocalDate immutable ve thread-safe'dir. Date, Java 8'den beri kullanımdan kaldırılmıştır.

Veritabanında LocalDateTime kullanılabilir mi?

Evet, LocalDateTime SQL türü TIMESTAMP WITHOUT TIME ZONE'a iyi şekilde eşlenir. JPA ve Room, TypeConverter aracılığıyla destekler. TIMESTAMP WITH TIME ZONE için ZonedDateTime veya OffsetDateTime kullanın.

İki tarih arasındaki gün sayısı nasıl alınır?

ChronoUnit.DAYS.between(startDate, endDate) kullanın. Bu yöntem long döndürür — gün cinsinden fark. Daha ayrıntılı hesaplama için, yıllar, aylar ve günlerle Period döndüren Period.between()'i kullanın.

Zaman hassasiyetini milisaniyeye kadar korumanız gerekiyorsa ne yapmalısınız?

LocalTime nanosaniye hassasiyetini (9 ondalık basamak) destekler. Milisaniye hassasiyeti yeterliyse, kaydetmeden önce truncateTo(ChronoUnit.MILLIS) kullanın. Bu, serileştirme sırasında yuvarlama sorunlarını önler.

LocalDate.now() neden farklı cihazlarda farklı tarihler döndürür?

now() yöntemi, cihazın sistem saatini ve varsayılan saat dilimini kullanır. Cihazlar farklı saat dilimlerindeyse, tarih farklı olabilir. Birleşik bir zaman damgası için her zaman UTC saatini döndüren Instant.now()'u kullanın.

Özet

  • LocalDate — saat ve saat dilimi olmadan tarih için immutable sınıf. Doğum günleri, son tarihler, etkinlik tarihleri saklamak için kullanılır.
  • LocalTime — nanosaniye hassasiyetinde günün saati için immutable sınıf. Açılış saatleri, işlem süreleri saklamak için uygundur.
  • LocalDateTime — saat dilimi bağlantısı olmadan tarih ve zaman birleşimi. En esnek yerel tür, ancak dağıtık sistemler için uygun değil.
  • Her üç sınıf da DateTimeFormatter tabanlı birleşik API aracılığıyla aritmetik, karşılaştırma, biçimlendirme ve ayrıştırmayı destekler.
  • Android'de java.time, API 26'dan itibaren yerleşik destek veya eski sürümler için desugaring aracılığıyla kullanılabilir.
  • Küresel zaman damgaları ve saat dilimi verileri için yerel türler yerine ZonedDateTime veya Instant kullanın.
  • Dizeleri ayrıştırırken, standart olmayan biçimler için her zaman bir DateTimeFormatter iletin ve DateTimeParseException'ı işleyin.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun