LocalDate, LocalTime va LocalDateTime — java.time paketining asosiy sinflari bo‘lib, vaqt mintaqasiga bog‘liq bo‘lmagan holda sana va vaqt bilan ishlashni ta’minlaydi. Oracle hujjatlariga (Java 17, 2024) ko‘ra, bu turlar immutable va thread-safe sifatida yaratilgan bo‘lib, bu ularni ko‘p oqimli ilovalar uchun xavfsiz qiladi. Ular Androidda API 26 dan boshlab desugaring orqali, eski versiyalar uchun esa ThreeTenABP kutubxonasi orqali mavjud bo‘ldi.
Asosiy ma’lumotlar
LocalDate — vaqt va vaqt mintaqasi haqida ma’lumotsiz sanani yil-oy-kun formatida ifodalovchi sinf. Tug‘ilgan kun, tadbir sanasi yoki amal qilish muddati kabi ma’lumotlarni saqlash uchun ishlatiladi.
LocalDate yilni -999999999 dan +999999999 gacha, oyni 1 dan 12 gacha va kunni kabisa yillari ni hisobga olgan holda saqlaydi. Sinf to‘liq immutable — har bir operatsiya yangi obyekt qaytaradi.
LocalTime kunning vaqtini ifodalaydi: soatlar, daqiqalar, soniyalar va nanosekundlar. Maksimal aniqlik — nanosekundgacha. LocalTime sana va vaqt mintaqasi haqida ma’lumotni o‘z ichiga olmaydi, bu uni do‘kon ochilish vaqti yoki jarayon davomiyligini saqlash uchun qulay qiladi.
LocalDateTime LocalDate va LocalTime ni bitta obyektda birlashtiradi. Bu sana va vaqtni saqlash kerak bo‘lganda eng ko‘p ishlatiladigan tur, lekin vaqt mintaqasiga bog‘liqlik talab qilinmaydi. Masalan, mahalliy formatdagi konsert sanasi va vaqti.
Oracle Java Documentation (2024) ga ko‘ra, uchala sinf ham Joda-Time kutubxonasi g‘oyalari asosida, ammo takomillashtirilgan arxitektura va standart kutubxonaga to‘liq integratsiya bilan yaratilgan.
java.time paketi Java 8 da eskirgan Date, Calendar va SimpleDateFormat sinflarining o‘rniga yaratilgan. Uning arxitekturasi immutable obyektlar va fluent-interfeys tamoyillariga asoslangan.
Asosiy xususiyat — barcha asosiy sinflar value-based dir. Bu ularning instansiyalari qiymat bo‘yicha solishtirilishini anglatadi, referens bo‘yicha emas, va ularni meros qilib bo‘lmaydi. Ikki obyektni solishtirish uchun == operatori emas, equals metodi ishlatiladi.
Paket bir necha kategoriyaga bo‘linadi. Vaqt mintaqasisiz turlar — LocalDate, LocalTime, LocalDateTime — mahalliy sana va vaqt uchun ishlatiladi. Vaqt mintaqali turlar — ZonedDateTime, OffsetDateTime, OffsetTime — siljish yoki zona haqida ma’lumot qo‘shadi. Oniy turlar — Instant — UTC dagi vaqt chizig‘idagi nuqtani ifodalaydi.
Bunday bo‘linish eski API ga xos muammoni hal qiladi: dasturchi Date obyekti vaqt mintaqasi haqida ma’lumotni o‘z ichiga oladimi yoki yo‘qmi, hech qachon bilmas edi. java.time da har bir tur o‘z semantikasini aniq e’lon qiladi.
LocalDate sinfi sanani yaratish, o‘qish va o‘zgartirish uchun ko‘plab metodlarni taqdim etadi. Joriy sanani now() statik metodi orqali olish mumkin. Muayyan sanani — of(int year, int month, int dayOfMonth) metodi orqali.
Sana komponentlarini o‘qish uchun getterlar ishlatiladi: getYear(), getMonthValue(), getDayOfMonth(), getDayOfWeek(), getDayOfYear(). getMonth() metodi Month enumini, getDayOfWeek() esa DayOfWeek enumini qaytaradi.
LocalDate sanalarni tekshirishni qo‘llab-quvvatlaydi. isBefore(), isAfter() va isEqual() metodlari sanalarni solishtirishga imkon beradi. isLeapYear() metodi yilning kabisa ekanligini tekshiradi. lengthOfMonth() metodi oydagi kunlar sonini, lengthOfYear() esa yildagi kunlar sonini qaytaradi.
O‘zgartirish uchun withYear(), withMonth(), withDayOfMonth() metodlari ishlatiladi, ular o‘zgartirilgan komponent bilan yangi obyekt qaytaradi. plusDays(), minusMonths() va shunga o‘xshash metodlar sana arifmetikasini bajaradi.
LocalTime kunning vaqtini nanosekundgacha aniqlik bilan ifodalaydi. Standart format — ISO-8601 (HH:mm:ss.nnnnnnnnn). Minimal qiymat — 00:00, maksimal — 23:59:59.999999999.
LocalTime obyektini now() bilan joriy vaqt uchun, of(int hour, int minute), of(int hour, int minute, int second) yoki of(int hour, int minute, int second, int nanoOfSecond) bilan yaratish mumkin. parse(CharSequence text) metodi ISO-8601 formatidagi qatorni tahlil qiladi.
Getterlar getHour(), getMinute(), getSecond(), getNano() ni o‘z ichiga oladi. toSecondOfDay() metodi kun boshidan boshlab soniyalar sonini, toNanoOfDay() esa nanosekundlarni qaytaradi. Bu bir kun ichida davomiylikni hisoblash uchun qulay.
LocalTime LocalDate bilan bir xil solishtirish va o‘zgartirish operatsiyalarini qo‘llab-quvvatlaydi: plusHours(), minusMinutes(), withHour(), withMinute(). isBefore() va isAfter() metodlari vaqtning kun davomida tsiklikligini hisobga olgan holda ishlaydi.
LocalDateTime LocalDate va LocalTime imkoniyatlarini bitta sinfda birlashtiradi. Sana va vaqtni saqlaydi, ammo vaqt mintaqasisiz. Bu mahalliy turlar ichida eng moslashuvchan tur, ammo taqsimlangan tizimlarda ehtiyotkorlik talab qiladi.
LocalDateTime yaratish uchun now(), of(LocalDate date, LocalTime time), of(int year, Month month, int dayOfMonth, int hour, int minute) statik metodlari va ularning overloadlari ishlatiladi. Shuningdek, LocalDate va LocalTime ni atTime() metodi orqali birlashtirish mumkin.
LocalDateTime tegishli getterlar orqali sana va vaqtning barcha maydonlariga kirishni ta’minlaydi: toLocalDate() va toLocalTime() alohida komponentlarni qaytaradi. truncatedTo(TemporalUnit unit) metodi vaqtni berilgan aniqlikka yaxlitlash imkonini beradi — masalan, daqiqalargacha.
Vaqt mintaqasiga o‘tkazish uchun ZonedDateTime qaytaradigan atZone(ZoneId zone) metodi ishlatiladi. Bu LocalDateTime ga vaqt mintaqasini qo‘shishning yagona usuli.
Uchala sinf ham statik fabrika metodlari orqali yagona yaratish namunasidan foydalanadi. Sinf konstruktorlari private deb e’lon qilingan — obyektni to‘g‘ridan-to‘g‘ri new orqali yaratib bo‘lmaydi.
Asosiy yaratish usullari:
of metodi ko‘plab overloadlarga ega. LocalDate uchun yil, oy va kun kerak. LocalTime uchun — soat va daqiqa (ixtiyoriy soniya va nanosekund). LocalDateTime uchun — yil, oy, kun, soat, daqiqa. Oyni int (1-12) yoki Month enum sifatida uzatish mumkin.
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)
java.time sinflari bir-biriga qulay konvertatsiya qilish uchun yaratilgan. LocalDate atTime(LocalTime) yoki atStartOfDay() metodi orqali LocalDateTime ga o‘tkazilishi mumkin. LocalTime — atDate(LocalDate) orqali.
LocalDateTime toLocalDate() orqali LocalDate ga va toLocalTime() orqali LocalTime ga qayta o‘tkazilishi mumkin. ZonedDateTime ga o‘tkazish uchun atZone(ZoneId) metodi ishlatiladi.
java.util.Date ga o‘tkazish (eski kod bilan moslik uchun) Instant va vaqt mintaqasi orqali oraliq qadam talab qiladi. Baeldung (2024) ga ko‘ra, bu operatsiya Date.from(instant) orqali amalga oshiriladi.
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"))
Formatlash va tahlil qilish uchun DateTimeFormatter sinfi ishlatiladi. U konstantalar (ISO_LOCAL_DATE, ISO_LOCAL_TIME, ISO_LOCAL_DATE_TIME) orqali oldindan belgilangan formatlar va namunalar orqali o‘z formatlarini yaratish imkoniyatini taqdim etadi.
Formatlash namunalari belgilardan foydalanadi: yyyy — yil, MM — oy (ikki raqamli), dd — kun, HH — soat (0-23), mm — daqiqa, ss — soniya. format() metodi sana-vaqt obyektida yoki DateTimeFormatter orqali chaqiriladi.
DateTimeFormatter shuningdek ofLocalizedDate(FormatStyle), ofLocalizedTime(FormatStyle) va ofLocalizedDateTime(FormatStyle) statik metodlari orqali lokalizatsiyani qo‘llab-quvvatlaydi. SHORT, MEDIUM, LONG va FULL stillari mavjud.
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")
)
Uchala sinf ham Comparable interfeysini amalga oshiradi, bu ularni tabiiy solishtirish imkonini beradi. compareTo() metodi tartibga qarab manfiy, nol yoki musbat son qaytaradi. isBefore(), isAfter() va isEqual() metodlari boolean qaytaradi.
LocalDate uchun solishtirish xronologik — erta sana kichikroq. LocalTime uchun — kunning vaqtiga ko‘ra. LocalDateTime uchun — avval sanaga, keyin vaqtga ko‘ra. Barcha solishtirishlar kabisa yillari va oylardagi kunlar sonini to‘g‘ri hisobga oladi.
Eski API dan muhim farq: LocalDate, LocalTime va LocalDateTime uchun equals() qiymatlarni solishtiradi, referenslarni emas. Bu degani, bir xil maydonlarga ega ikki obyekt teng bo‘ladi, hatto ular turli instansiyalar bo‘lsa ham.
val d1 = LocalDate.of(2026, 7, 21)
val d2 = LocalDate.of(2026, 12, 25)
if (d1.isBefore(d2)) {
Log.d("Sana", "d1 d2 dan oldin")
}
val sortedDates = listOf(d2, d1).sorted()
Uchala sinf ham plus va minus metodlari orqali arifmetik operatsiyalarni qo‘llab-quvvatlaydi. LocalDate uchun plusDays(), plusWeeks(), plusMonths(), plusYears() va shunga o‘xshash minus-metodlar mavjud. LocalTime plusHours(), plusMinutes(), plusSeconds(), plusNanos() ni qo‘llab-quvvatlaydi.
LocalDateTime ikkala turning barcha arifmetik operatsiyalarini meros qilib oladi. LocalDate xususiyati: oy qo‘shganda natijalar oylarning turli uzunligini to‘g‘ri boshqaradi. Masalan, 31 yanvar + 1 oy = 28 (kabisa yilda 29) fevral.
Murakkab operatsiyalar uchun Period (sanalar uchun) va Duration (vaqt uchun) sinflari mavjud. plus(TemporalAmount) va minus(TemporalAmount) metodlari bu obyektlarni qabul qiladi.
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)
Amaliy misolni ko‘rib chiqaylik: ish smenalari hisobini yuritish ilovasi. Smena davomiyligini hisoblash va uning tungi vaqtga to‘g‘ri kelishini aniqlash kerak. Boshlanish va tugash vaqti uchun LocalTime, sana uchun LocalDate va yarim tundan o‘tadigan smenalarni hisoblash uchun LocalDateTime dan foydalanamiz.
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()
}
}
Ikkinchi misol — foydalanuvchi yoshini hisoblash. Tug‘ilgan sana uchun LocalDate dan foydalanamiz va tug‘ilgan kun va oyni hisobga olgan holda joriy sana bilan solishtiramiz.
fun calculateAge(birthDate: LocalDate): Int {
val today = LocalDate.now()
val period = Period.between(birthDate, today)
return period.years
}
Uchinchi misol — bildirishnomalar bilan ishlash. LocalDateTime eslatmalarni rejalashtirish uchun ishlatiladi. Rejalashtirilgan vaqt kelganligini tekshiramiz.
data class Reminder(
val id: Long,
val scheduledAt: LocalDateTime
) {
fun isDue(): Boolean =
LocalDateTime.now().isAfter(scheduledAt)
}
java.time uchun o‘rnatilgan qo‘llab-quvvatlash Androidda API 26 (Android 8.0 Oreo) dan boshlab mavjud bo‘ldi. Androidning eski versiyalari bo‘lgan qurilmalar uchun desugaring — yangi Java API larini eski versiyalarda qo‘llab-quvvatlash mexanizmidan foydalanish kerak.
Android Gradle Plugin da desugaring build.gradle faylidagi compileOptions orqali sozlanadi. isCoreLibraryDesugaringEnabled = true ni o‘rnatish va desugar_jdk_libs kutubxonasini qo‘shish kifoya. Shundan so‘ng java.time API darajasi 14 dan boshlab barcha API darajalari uchun mavjud bo‘ladi.
Desugaring ni ishlata olmaydigan loyihalar uchun (masalan, AGP 4.0 dan past bo‘lgan eski loyihalar) ThreeTenABP kutubxonasi — java.time backporti mavjud. U bir xil sinflarni (LocalDate, LocalTime, LocalDateTime) taqdim etadi, ammo org.threeten.bp paketida.
@Suppress("UnstableApiUsage")
android {
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
}
dependencies {
"coreLibraryDesugaring"("com.android.tools:desugar_jdk_libs:2.1.4")
}
Birinchi keng tarqalgan xato — vaqt mintaqasini hisobga olmasdan taqsimlangan tizimlarda LocalDateTime dan foydalanish. Agar server Europe/Moscow da, mijoz esa Asia/Tokyo da bo‘lsa, LocalDateTime turlicha talqin qilinadi. Yechim: global ma’lumotlar uchun Instant yoki ZonedDateTime dan foydalaning.
Ikkinchi xato — qatorlarni noto‘g‘ri tahlil qilish. LocalDate.parse() standart bo‘yicha ISO-8601 (yyyy-MM-dd) formatini kutadi. Agar qator boshqa formatda bo‘lsa, DateTimeFormatter ni aniq uzatish kerak. Shuningdek, noto‘g‘ri kiritishda ilova ishdan chiqmasligi uchun DateTimeParseException ni boshqarish kerak.
Uchinchi xato — null-xavfsizlikni e’tiborsiz qoldirish. LocalDate, LocalTime va LocalDateTime null bo‘lishi mumkin bo‘lgan obyektlardir. Kotlin da aniq tekshirish yoki Elvis operatori bilan nullable turlardan foydalanish tavsiya etiladi. Java da — metodlarni chaqirishdan oldin null ekanligini tekshiring.
To‘rtinchi xato — LocalDateTime va ZonedDateTime ni adashtirish. LocalDateTime vaqt mintaqasi haqida hech qanday ma’lumotga ega emas. Agar mutlaq vaqt momentini uzatish kerak bo‘lsa — zonal turlardan foydalaning. Agar mahalliy vaqt yetarli bo‘lsa — mahalliy turlardan.
Tez-tez beriladigan savollar
Date 1970-01-01 UTC dan millisekundlar sonini saqlaydi, LocalDate esa yil, oy va kunni vaqt mintaqasiga bog‘liq bo‘lmagan holda saqlaydi. Date o‘zgartiriladigan va thread-safe emas, LocalDate — immutable va thread-safe. Date Java 8 dan boshlab eskirgan.
Ha, LocalDateTime SQL TIMESTAMP WITHOUT TIME ZONE turiga yaxshi mos keladi. JPA va Room uni TypeConverter orqali qo‘llab-quvvatlaydi. TIMESTAMP WITH TIME ZONE uchun ZonedDateTime yoki OffsetDateTime dan foydalaning.
ChronoUnit.DAYS.between(startDate, endDate) dan foydalaning. Bu metod long — kunlardagi farqni qaytaradi. Batafsil hisoblash uchun Period.between() dan foydalaning, u yillar, oylar va kunlar bilan Period qaytaradi.
LocalTime nanosekundgacha aniqlikni qo‘llab-quvvatlaydi (verguldan keyin 9 raqam). Millisekund aniqlik kerak bo‘lsa, saqlashdan oldin truncateTo(ChronoUnit.MILLIS) dan foydalaning. Bu serializatsiya paytida yaxlitlash muammolarini oldini oladi.
now() metodi qurilmaning tizim soati va standart vaqt mintaqasidan foydalanadi. Qurilmalar turli vaqt mintaqalarida bo‘lsa, sana farq qilishi mumkin. Yagona vaqt tamg‘asi uchun har doim UTC vaqtini qaytaradigan Instant.now() dan foydalaning.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.