LocalDate, LocalTime və LocalDateTime: bu nədir, tarixlə iş

Müəllif: IT Sectr Dərc olunub: 2026-07-13 Oxuma vaxtı: 12 dəq

LocalDate, LocalTime və LocalDateTime — java.time paketinin əsas sinifləri olub, saat qurşağına bağlı olmadan tarix və vaxtla işləməyi təmin edir. Oracle sənədlərinə (Java 17, 2024) görə, bu tiplər immutable və thread-safe olaraq dizayn edilmişdir ki, bu da onları çoxiplikli tətbiqlər üçün təhlükəsiz edir. Onlar Android-də API 26-dan başlayaraq desugaring vasitəsilə, köhnə versiyalar üçün isə ThreeTenABP kitabxanası vasitəsilə əlçatan oldu.

Əsas məqamlar

  • LocalDate — vaxt və saat qurşağı olmadan tarixi (il, ay, gün) təmsil edən immutable sinif.
  • LocalTime — tarix və saat qurşağı olmadan vaxtı (saat, dəqiqə, saniyə, nanosaniyə) təmsil edən immutable sinif.
  • LocalDateTime — LocalDate və LocalTime-in kombinasiyası, zonaya bağlı olmadan həm tarixi, həm də vaxtı saxlayır.
  • Hər üç sinif arifmetik əməliyyatları dəstəkləyir — plus və minus metodları vasitəsilə gün, ay, saat əlavə etmə və çıxma.
  • Android-də bu tiplər desugaring (API 26+) və ya ThreeTenABP kitabxanası (API < 26) vasitəsilə əlçatandır.

LocalDate, LocalTime və LocalDateTime nədir?

LocalDate — vaxt və saat qurşağı haqqında məlumat olmadan ili-ayı-günü formatında tarixi təmsil edən sinif. Doğum günü, tədbir tarixi və ya etibarlılıq müddəti kimi məlumatları saxlamaq üçün istifadə olunur.

LocalDate ili -999999999-dan +999999999-a qədər, ayı 1-dən 12-yə qədər və günü uzun illər nəzərə alınmaqla saxlayır. Sinif tamamilə immutable-dır — hər əməliyyat yeni obyekt qaytarır.

LocalTime günün vaxtını təmsil edir: saatlar, dəqiqələr, saniyələr və nanosaniyələr. Maksimum dəqiqlik — nanosaniyəyə qədər. LocalTime tarix və saat qurşağı haqqında məlumat ehtiva etmir, bu da onu mağazanın açılış saatı və ya prosesin müddətini saxlamaq üçün əlverişli edir.

LocalDateTime LocalDate və LocalTime-i bir obyektdə birləşdirir. Həm tarix, həm də vaxt saxlamaq lazım olduqda, lakin saat qurşağına bağlılıq tələb olunmadıqda ən çox istifadə olunan tipdir. Məsələn, yerli formatda konsertin tarixi və saatı.

Oracle Java Documentation (2024)-yə görə, hər üç sinif Joda-Time kitabxanasının ideyaları əsasında, lakin təkmilləşmiş arxitektura və standart kitabxanaya tam inteqrasiya ilə dizayn edilmişdir.

java.time paketi necə qurulub?

java.time paketi Java 8-də köhnəlmiş Date, Calendar və SimpleDateFormat siniflərinin əvəzi olaraq ortaya çıxdı. Onun arxitekturası immutable obyektlər və fluent-interfeys prinsipləri üzərində qurulub.

Əsas xüsusiyyət — bütün əsas siniflər value-based-dır. Bu o deməkdir ki, onların instansiyaları referansa görə deyil, dəyərə görə müqayisə olunur və onları miras almaq olmaz. İki obyekti müqayisə etmək üçün == operatoru yox, equals metodu istifadə olunur.

Paket bir neçə kateqoriyaya bölünür. Saat qurşağı olmayan tiplər — LocalDate, LocalTime, LocalDateTime — yerli tarix və vaxt üçün istifadə olunur. Saat qurşağı olan tiplər — ZonedDateTime, OffsetDateTime, OffsetTime — yerdəyişmə və ya zona haqqında məlumat əlavə edir. Anlıq tiplər — Instant — UTC-də vaxt xəttində nöqtəni təmsil edir.

Belə bölgü köhnə API-ə xas olan problemi həll edir: proqramçı Date obyektinin saat qurşağı haqqında məlumat ehtiva edib-etmədiyini heç vaxt bilmirdi. java.time-da hər bir tip öz semantikasını açıqca bəyan edir.

LocalDate: tarixlə iş

LocalDate sinfi tarixin yaradılması, oxunması və dəyişdirilməsi üçün çoxlu metod təqdim edir. Cari tarixi now() statik metodu vasitəsilə əldə etmək olar. Müəyyən bir tarixi — of(int year, int month, int dayOfMonth) metodu ilə.

Tarixin komponentlərini oxumaq üçün getterlər istifadə olunur: getYear(), getMonthValue(), getDayOfMonth(), getDayOfWeek(), getDayOfYear(). getMonth() metodu Month enumunu, getDayOfWeek() isə DayOfWeek enumunu qaytarır.

LocalDate tarixlərin yoxlanılmasını dəstəkləyir. isBefore(), isAfter() və isEqual() metodları tarixləri müqayisə etməyə imkan verir. isLeapYear() metodu ilin uzun olub-olmadığını yoxlayır. lengthOfMonth() metodu aydakı günlərin sayını, lengthOfYear() isə ildəki günlərin sayını qaytarır.

Dəyişiklik üçün withYear(), withMonth(), withDayOfMonth() metodları istifadə olunur ki, bunlar dəyişdirilmiş komponentlə yeni obyekt qaytarır. plusDays(), minusMonths() və analoji metodlar tarix arifmetikasını yerinə yetirir.

LocalTime: vaxtla iş

LocalTime günün vaxtını nanosaniyəyə qədər dəqiqliklə təmsil edir. Standart format — ISO-8601 (HH:mm:ss.nnnnnnnnn). Minimum dəyər — 00:00, maksimum — 23:59:59.999999999.

LocalTime obyektini now() ilə cari vaxt üçün, of(int hour, int minute), of(int hour, int minute, int second) və ya of(int hour, int minute, int second, int nanoOfSecond) ilə yaratmaq olar. parse(CharSequence text) metodu ISO-8601 formatında sətri pars edir.

Getterlərə getHour(), getMinute(), getSecond(), getNano() daxildir. toSecondOfDay() metodu günün əvvəlindən saniyələrin sayını, toNanoOfDay() isə nanosaniyələri qaytarır. Bu, bir gün ərzində müddət hesablamaları üçün əlverişlidir.

LocalTime LocalDate ilə eyni müqayisə və dəyişiklik əməliyyatlarını dəstəkləyir: plusHours(), minusMinutes(), withHour(), withMinute(). isBefore() və isAfter() metodları vaxtın gün ərzində dövrü olmasını nəzərə alaraq işləyir.

LocalDateTime: tarix və vaxtın kombinasiyası

LocalDateTime LocalDate və LocalTime-in imkanlarını bir sinifdə birləşdirir. Tarix və vaxtı saxlayır, lakin saat qurşağı olmadan. Bu, lokal tiplər içərisində ən çevik tipdir, lakin paylanmış sistemlərdə istifadə edərkən ehtiyat tələb edir.

LocalDateTime yaratmaq üçün now(), of(LocalDate date, LocalTime time), of(int year, Month month, int dayOfMonth, int hour, int minute) statik metodları və onların overloadları istifadə olunur. Həmçinin LocalDate və LocalTime-i atTime() metodu vasitəsilə birləşdirmək olar.

LocalDateTime müvafiq getterlər vasitəsilə tarix və vaxtın bütün sahələrinə giriş təmin edir: toLocalDate() və toLocalTime() ayrı-ayrı komponentləri qaytarır. truncatedTo(TemporalUnit unit) metodu vaxtı müəyyən dəqiqliyə yuvarlaqlaşdırmağa imkan verir — məsələn, dəqiqələrə qədər.

Saat qurşağına çevirmək üçün ZonedDateTime qaytaran atZone(ZoneId zone) metodu istifadə olunur. Bu, LocalDateTime-ə saat qurşağı əlavə etməyin yeganə yoludur.

Tarix və vaxt obyektlərini necə yaratmalı?

Hər üç sinif statik fabrik metodları vasitəsilə vahid yaradılma nümunəsindən istifadə edir. Siniflərin konstruktorları private elan edilmişdir — obyekti birbaşa new ilə yaratmaq mümkün deyil.

Əsas yaratma üsulları:

  • now() — sistem saatından cari tarix/vaxt
  • of(...) — komponentlərdən (il, ay, gün və s.)
  • parse(String) — ISO-8601 formatında sətrdən
  • from(TemporalAccessor) — başqa temporal obyektdən

of metodu çoxlu overloadlara malikdir. LocalDate üçün il, ay və gün lazımdır. LocalTime üçün — saat və dəqiqə (istəyə bağlı saniyə və nanosaniyə). LocalDateTime üçün — il, ay, gün, saat, dəqiqə. Ayı int (1-12) və ya Month enumu kimi ötürmək olar.

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)

Tiplər arası çevirmə

java.time sinifləri bir-birinə rahat çevirmə üçün dizayn edilmişdir. LocalDate atTime(LocalTime) və ya atStartOfDay() metodu vasitəsilə LocalDateTime-ə çevrilə bilər. LocalTime — atDate(LocalDate) vasitəsilə.

LocalDateTime toLocalDate() vasitəsilə LocalDate-ə və toLocalTime() vasitəsilə LocalTime-ə geri çevrilə bilər. ZonedDateTime-ə çevirmək üçün atZone(ZoneId) metodu istifadə olunur.

java.util.Date-ə çevirmə (köhnə kodla uyğunluq üçün) Instant və saat qurşağı vasitəsilə aralıq addım tələb edir. Baeldung (2024)-yə görə, bu əməliyyat Date.from(instant) vasitəsilə yerinə yetirilir.

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"))

Formatlaşdırma və pars etmə

Formatlaşdırma və pars etmə üçün DateTimeFormatter sinfindən istifadə olunur. O, sabitlər (ISO_LOCAL_DATE, ISO_LOCAL_TIME, ISO_LOCAL_DATE_TIME) vasitəsilə əvvəlcədən təyin edilmiş formatlar və nümunə sətrləri vasitəsilə öz formatlarını yaratmaq imkanı təqdim edir.

Formatlaşdırma nümunələri simvollardan istifadə edir: yyyy — il, MM — ay (iki rəqəmli), dd — gün, HH — saat (0-23), mm — dəqiqə, ss — saniyə. format() metodu tarix-vaxt obyektində və ya DateTimeFormatter vasitəsilə çağrılır.

DateTimeFormatter həmçinin ofLocalizedDate(FormatStyle), ofLocalizedTime(FormatStyle) və ofLocalizedDateTime(FormatStyle) statik metodları vasitəsilə lokalizasiyanı dəstəkləyir. SHORT, MEDIUM, LONG və FULL stilləri mövcuddur.

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")
)

Tarix-vaxt obyektlərinin müqayisəsi

Hər üç sinif Comparable interfeysini tətbiq edir ki, bu da onların təbii şəkildə müqayisəsinə imkan verir. compareTo() metodu sıralamadan asılı olaraq mənfi, sıfır və ya müsbət ədəd qaytarır. isBefore(), isAfter() və isEqual() metodları boolean qaytarır.

LocalDate üçün müqayisə xronoloji olaraq aparılır — daha erkən tarix daha kiçikdir. LocalTime üçün — günün vaxtına görə. LocalDateTime üçün — əvvəlcə tarixə, sonra vaxta görə. Bütün müqayisələr uzun illəri və aylardakı günlərin sayını düzgün nəzərə alır.

Köhnə API-dən mühüm fərq: LocalDate, LocalTime və LocalDateTime üçün equals() referansları deyil, dəyərləri müqayisə edir. Bu o deməkdir ki, eyni sahələrə malik iki obyekt fərqli instansiyalar olsa belə bərabər olacaqdır.

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

if (d1.isBefore(d2)) {
    Log.d("Tarix", "d1 d2-dən əvvəldir")
}

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

Tarix və vaxtın arifmetikası

Hər üç sinif plusminus metodları vasitəsilə arifmetik əməliyyatları dəstəkləyir. LocalDate üçün plusDays(), plusWeeks(), plusMonths(), plusYears() və analoji minus-metodlar mövcuddur. LocalTime plusHours(), plusMinutes(), plusSeconds(), plusNanos()-ı dəstəkləyir.

LocalDateTime hər iki tipin bütün arifmetik əməliyyatlarını miras alır. LocalDate-in xüsusiyyəti: ay əlavə edərkən nəticələr ayların müxtəlif uzunluğunu düzgün nəzərə alır. Məsələn, 31 yanvar + 1 ay = 28 (uzun ildə 29) fevral.

Daha mürəkkəb əməliyyatlar üçün Period (tarixlər üçün) və Duration (vaxt üçün) sinifləri mövcuddur. plus(TemporalAmount) və minus(TemporalAmount) metodları bu obyektləri qəbul edir.

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-də kod nümunələri

Praktik nümunəyə baxaq: iş növbələrinin uçotu tətbiqi. Növbənin müddətini hesablamaq və onun gecə vaxtına düşüb-düşmədiyini müyyən etmək lazımdır. Başlanğıc və bitiş vaxtı üçün LocalTime, tarix üçün LocalDate və gecə yarısını keçən növbələrin hesablamaları üçün LocalDateTime istifadə edirik.

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 nümunə — istifadəçinin yaşının hesablanması. Doğum tarixi üçün LocalDate istifadə edirik və cari tarixlə müqayisə edirik, doğum günü və ayını nəzərə alaraq.

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

Üçüncü nümunə — bildirişlərlə iş. LocalDateTime xatırlatmaları planlaşdırmaq üçün istifadə olunur. Planlaşdırılmış vaxtın çatıb-çatmadığını yoxlayırıq.

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

Android-də dəstək: API səviyyəsi və desugaring

java.time üçün daxili dəstək Android-də API 26-dan (Android 8.0 Oreo) başlayaraq mövcud oldu. Android-in köhnə versiyaları olan cihazlar üçün desugaring — erkən versiyalarda yeni Java API-lərinə dəstək əlavə edən mexanizmdən istifadə etmək lazımdır.

Android Gradle Plugin-də desugaring build.gradle faylında compileOptions vasitəsilə konfiqurasiya olunur. isCoreLibraryDesugaringEnabled = true təyin etmək və desugar_jdk_libs kitabxanasını əlavə etmək kifayətdir. Bundan sonra java.time API səviyyəsi 14-dən başlayaraq bütün API səviyyələri üçün əlçatan olur.

Desugaring istifadə edə bilməyən layihələr üçün (məsələn, AGP 4.0-dan aşağı olan köhnə layihələr) ThreeTenABP kitabxanası — java.time backport-u mövcuddur. O, eyni sinifləri (LocalDate, LocalTime, LocalDateTime) təqdim edir, lakin org.threeten.bp paketində.

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

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

Tipik səhvlər və onlardan necə qaçınmaq

Birinci geniş yayılmış səhv — saat qurşağını nəzərə almadan paylanmış sistemlərdə LocalDateTime istifadə etmək. Server Europe/Moscow-da, müştəri isə Asia/Tokyo-dadırsa, LocalDateTime fərqli şəkildə şərh ediləcək. Həll yolu: qlobal məlumatlar üçün Instant və ya ZonedDateTime istifadə edin.

İkinci səhv — sətrlərin səhv pars edilməsi. LocalDate.parse() standart olaraq ISO-8601 (yyyy-MM-dd) formatını gözləyir. Sətr başqa formatdadırsa, DateTimeFormatter açıqca ötürülməlidir. Həmçinin, səhv daxiletmə zamanı tətbiqin çökməməsi üçün DateTimeParseException-i idarə etmək lazımdır.

Üçüncü səhv — null-təhlükəsizliyin görməməzdən gəlinməsi. LocalDate, LocalTime və LocalDateTime null ola bilən obyektlərdir. Kotlin-də açıq yoxlama və ya Elvis operatoru ilə nullable tiplərdən istifadə etmək tövsiyə olunur. Java-da — metodları çağırmazdan əvvəl null olub-olmadığını yoxlayın.

Dördüncü səhv — LocalDateTime ilə ZonedDateTime arasında qarışıqlıq. LocalDateTime saat qurşağı haqqında heç bir məlumat ehtiva etmir. Mütləq vaxt anını ötürmək lazımdırsa — zonal tiplərdən istifadə edin. Yerli vaxt kifayətdirsə — lokal tiplərdən.

Tez-tez verilən suallar

Java-da LocalDate və Date arasındakı fərq nədir?

Date 1970-01-01 UTC-dən millisaniyələrin sayını saxlayır, LocalDate isə il, ay və günü saat qurşağına bağlı olmadan saxlayır. Date mutasiya olunandır və thread-safe deyil, LocalDate — immutable və thread-safe-dir. Date Java 8-dən etibarən köhnəlmişdir.

LocalDateTime məlumat bazasında istifadə edilə bilərmi?

Bəli, LocalDateTime SQL TIMESTAMP WITHOUT TIME ZONE tipinə yaxşı map olunur. JPA və Room onu TypeConverter vasitəsilə dəstəkləyir. TIMESTAMP WITH TIME ZONE üçün ZonedDateTime və ya OffsetDateTime istifadə edin.

İki tarix arasında günlərin sayını necə əldə etmək olar?

ChronoUnit.DAYS.between(startDate, endDate) istifadə edin. Bu metod long — günlər fərqini qaytarır. Daha ətraflı hesablama üçün Period.between() istifadə edin, o, illər, aylar və günlərlə Period qaytarır.

Millisaniyəyə qədər vaxt dəqiqliyini qorumaq lazımdırsa nə etməli?

LocalTime nanosaniyəyə qədər dəqiqliyi dəstəkləyir (vergüldən sonra 9 rəqəm). Millisaniyə dəqiqliyi lazımdırsa, yazmazdan əvvəl truncateTo(ChronoUnit.MILLIS) istifadə edin. Bu, serializasiya zamanı yuvarlaqlaşdırma problemlərinin qarşısını alır.

Niyə LocalDate.now() müxtəlif cihazlarda fərqli tarix qaytarır?

now() metodu cihazın sistem saatından və standart saat qurşağından istifadə edir. Cihazlar müxtəlif saat qurşaqlarındadırsa, tarix fərqlənə bilər. Vahid vaxt damğası üçün həmişə UTC-də vaxtı qaytaran Instant.now() istifadə edin.

Nəticə

  • LocalDate — vaxt və saat qurşağı olmadan tarix üçün immutable sinif. Doğum günləri, müddətlər, tədbir tarixlərini saxlamaq üçün istifadə olunur.
  • LocalTime — nanosaniyəyə qədər dəqiqliklə günün vaxtı üçün immutable sinif. Açılış saatlarını, proses müddətlərini saxlamaq üçün uyğundur.
  • LocalDateTime — zonaya bağlı olmadan tarix və vaxtın kombinasiyası. Ən çevik lokal tip, lakin paylanmış sistemlər üçün uyğun deyil.
  • Hər üç sinif DateTimeFormatter-a əsaslanan vahid API vasitəsilə arifmetika, müqayisə, formatlaşdırma və pars etməni dəstəkləyir.
  • Android-də java.time daxili dəstəklə API 26-dan və ya köhnə versiyalar üçün desugaring vasitəsilə əlçatandır.
  • Qlobal vaxt damğaları və saat qurşağı olan məlumatlar üçün lokal tiplər əvəzinə ZonedDateTime və ya Instant istifadə edin.
  • Sətrləri pars edərkən qeyri-standart formatlar üçün həmişə DateTimeFormatter ötürün və DateTimeParseException-i idarə edin.

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun