Joda-Time — Java-da sanalar va vaqt bilan ishlash uchun kutubxona bo'lib, Stiven Koulburn tomonidan noqulay java.util.Date va java.util.Calendar-ga muqobil sifatida yaratilgan. Java 8 chiqishidan oldin bu kutubxona sanoat ishlanmalarida, jumladan Android ilovalarida sanalar bilan ishlash uchun de-fakto standart edi. Oracle Java Magazine (2023) ma'lumotlariga ko'ra, loyihalarning 60% dan ortig'i Android API 26 chiqqandan keyin ikki yil ichida Joda-Time-dan java.time-ga migratsiya qildi.
Asosiy fikrlar
Joda-Time — Java tilida java.util.Date va java.util.Calendar sinflariga sifatli o'rinbosar beruvchi ochiq kodli (Apache 2.0) kutubxona. Loyiha Stiven Koulburn tomonidan 2004-yilda standart sana API-larining ko'plab muammolariga, jumladan o'zgaruvchanlik, formatlash murakkabligi va vaqt mintaqalarining cheklangan qo'llab-quvvatlashiga javoban asos solingan. Kutubxona Java hamjamiyatida keng tarqaldi va minglab loyihalarda, jumladan yirik enterprise tizimlari va Android ilovalarida ishlatildi, bunda o'rnatilgan sana vositalari ayniqsa noqulay edi. 2014-yilda Java 8 chiqishi va java.time (JSR-310) paketi paydo bo'lishidan boshlab kutubxona qo'llab-quvvatlash rejimiga o'tkazildi — yangi funksiyalar qo'shilmaydi, mavjud funksionallik esa yangi API tomonidan to'liq qoplanadi.
Joda-Time o'zgarmaslik printsipida qurilgan: yaratilgandan so'ng har bir sana yoki vaqt obyektini o'zgartirib bo'lmaydi. Har qanday operatsiya — kun qo'shish, oyni o'zgartirish, vaqt mintaqasini o'rnatish — asl nusxani o'zgarishsiz qoldirib, yangi obyekt qaytaradi. Bunday yondashuv o'zgaruvchan java.util.Date va java.util.Calendar-ga xos bo'lgan obyektlarning beixtiyor o'zgartirilishi bilan bog'liq xatolar sinfini butunlay yo'q qiladi. O'zgarmas dizayn shuningdek kutubxonani qo'shimcha sinxronizatsiyasiz ip-xavfsiz qiladi.
Kutubxona turli stsenariylar uchun bir nechta asosiy sinflarni taqdim etadi: DateTime — vaqt mintaqasi bilan to'liq sana va vaqt, LocalDate — vaqtsiz faqat sana, LocalTime — sanasiz faqat vaqt, LocalDateTime — mintaqaga bog'liq bo'lmagan sana va vaqt. Bundan tashqari, intervallar (Interval), davrlar (Period) va muddatlar (Duration) bilan ishlash uchun sinflar kiritilgan bo'lib, ular turli o'lchov birliklarida ikki vaqt momenti o'rtasidagi farqni hisoblash imkonini beradi. Har bir sinf yagona ishlov berish uchun ReadableInstant yoki ReadablePartial interfeysini amalga oshiradi.
Java-da standart sana API-larining muammosi platforma paydo bo'lganidan beri ma'lum edi. java.util.Date va java.util.Calendar sinflari fundamental kamchiliklarga ega edi: oylar 0 dan raqamlangan, Date bir vaqtning o'zida ham sanani, ham vaqtni ifodalagan, Calendar o'zgaruvchan edi va murakkab sozlashni talab qilgan. SimpleDateFormat orqali formatlash ip-xavfsiz emas edi — ko'p ipli ilovalarda bu sanalarni noto'g'ri tahlil qilishga olib kelgan. Stiven Koulburn sanalardan intensiv foydalanadigan loyihalar ustida ishlab, barcha bu muammolarni tuzatadigan muqobil yaratishga qaror qildi.
InfoQ (2014) intervyusiga ko'ra, Koulburn Joda-Time-ni birinchi ommaviy chiqarilishidan oldin bir yildan ortiq sanoat loyihalarida sinovdan o'tkazgan. Birinchi versiya 2004-yilda chiqdi va darhol hamjamiyat e'tiborini tortdi. 2010-yilga kelib kutubxona Spring va Hibernate kabi freymvorklarni ham o'z ichiga olgan ko'pchilik Java loyihalarida standart bog'liqlikka aylandi. Joda-Time muvaffaqiyati Java 8-ga kiritilgan JSR-310 (Date and Time API) spetsifikatsiyasiga bevosita ta'sir ko'rsatdi — spetsifikatsiya muallifi esa xuddi shu Stiven Koulburn edi.
Joda-Time nafaqat sana muammosini hal qildi — Java-da API dizayniga yondashuvni o'zgartirdi. Kutubxona tomonidan namoyish etilgan o'zgarmas qiymat obyektlari konsepsiyasi Java 8-da barcha yangi API-lar uchun standart sifatida qabul qilindi. Bundan tashqari, Joda-Time-ning mashhurligi Oracle-ga hamjamiyat sifatsiz standart kutubxonalarga chidashga tayyor emasligini ko'rsatdi — Joda-Time-dan so'ng Java-da fayllar (NIO.2), vaqt (java.time) va ixtiyoriy qiymatlar (Optional) bilan ishlash uchun API-lar qayta ishlab chiqildi.
Joda-Time Java 8 dan oldin standart kutubxonada mavjud bo'lmagan imkoniyatlar to'plamini taqdim etadi. Asosiy afzalliklar 200 dan ortiq vaqt mintaqalarini qo'llab-quvvatlash yoz vaqtini avtomatik qayta ishlash bilan, naqshlar va lokallar bilan boy formatlash API-si, shuningdek turli birliklarda — yillar, oylar, kunlar, soatlarda sanalar o'rtasidagi davrlarni hisoblashni o'z ichiga oladi. Alohida e'tiborga interval tizimi loyiq: Interval (ikki moment o'rtasidagi bo'shliq), Period (kalendar birliklaridagi farq) va Duration (millisekundlardagi aniq muddat).
Joda-Time-dagi DateTimeFormatter sinfi java.text.SimpleDateFormat-dan farqli o'laroq, ip-xavfsiz sana formatlashni ta'minlaydi. Formatlagichlar naqshlar (masalan, "yyyy-MM-dd HH:mm:ss") yoki lokallashtirilgan chiqish uchun uslublar (SHORT, MEDIUM, LONG, FULL) orqali yaratilishi mumkin. Kutubxona shuningdek yuqori yuklangan ilovalarda ishni tezlashtiradigan formatlagich keshlashni qo'llab-quvvatlaydi. Satrlardan sanalarni tahlil qilish qat'iylik nazorati bilan amalga oshiriladi — to'liq bo'lmagan yoki noto'g'ri sanalarga ruxsat berish yoki taqiqlash mumkin.
Joda-Time ning kuchli tomonlaridan biri vaqt oralig'i bilan ishlashdir. Interval sinfi ikki moment (Instant) o'rtasidagi aniq vaqt kesimini ifodalaydi va kesishish, birlashtirish va tegishlilikni tekshirish operatsiyalarini qo'llab-quvvatlaydi. Period, Interval-dan farqli o'laroq, kalendar birliklari bilan ishlaydi — masalan, 1-mart va 1-aprel o'rtasidagi farq aniq 1 oy, garchi muddat jihatidan 28–31 kun bo'lishi mumkin. Duration esa kalendarga bog'liq bo'lmagan holda millisekundlarda aniq muddatni ifodalaydi va operatsiyalarning bajarilish vaqtini o'lchash uchun mos keladi.
import org.joda.time.*;
import org.joda.time.format.*;
DateTime now = new DateTime();
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
String formatted = fmt.print(now);
DateTime nextWeek = now.plusWeeks(1);
Period period = new Period(now, nextWeek);
int days = period.getDays(); // kunlar = 7
Interval interval = new Interval(now, nextWeek);
boolean contains = interval.contains(now); // true
java.time (JSR-310) paketi xuddi shu muallif — Stiven Koulburn tomonidan ishlab chiqilgan va o'n yillik ekspluatatsiya tajribasini hisobga olgan holda Joda-Time-ning eng yaxshi g'oyalarini o'ziga singdirgan. Ikkala API ham o'zgarmas sinflardan foydalanadi, vaqt mintaqalarini qo'llab-quvvatlaydi va boy operatsiyalar to'plamini taqdim etadi. Biroq, java.time Java-ning standart kutubxonasiga to'liq integratsiyalangan, tashqi bog'liqliklarni talab qilmaydi va yanada izchil nomlash tizimidan foydalanadi: ReadableInstant o'rniga Instant, LocalDate o'rniga LocalDate (nom saqlangan), DateTime o'rniga ZonedDateTime.
| Xususiyat | Joda-Time | java.time |
|---|---|---|
| Chiqish yili | 2004 | 2014 (Java 8) |
| Holat | Qo'llab-quvvatlash (maintenance) | Faol rivojlanish |
| Asosiy sana/vaqt | DateTime | ZonedDateTime |
| Faqat sana | LocalDate | LocalDate |
| O'zgarmaslik | Ha | Ha |
| Formatlash | DateTimeFormatter | DateTimeFormatter |
| Sana farqi | Period / Duration | Period / Duration |
java.time Joda-Time-ning bir nechta arxitektura qarorlarini tuzatadi. Birinchidan, java.time-da null qaytaradigan metodlar va mavjud bo'lmagan qiymatlar o'rtasidagi chalkashlik bartaraf etilgan — buning o'rniga Optional ishlatiladi. Ikkinchidan, Chronology interfeysi orqali muqobil kalendar tizimlarining (Yapon, Tay, Islom) qo'llab-quvvatlashi qo'shilgan. Uchinchidan, java.time kalendarga bog'liq bo'lmagan holda UTC vaqt momentlari bilan ishlash uchun Instant sinfini o'z ichiga oladi — bu tarmoq protokollari va ma'lumotlar bazalari bilan integratsiyani soddalashtiradi. Android uchun API 26 (Android 8.0) dan boshlab java.time dan foydalanish tavsiya etiladi yoki eski versiyalar uchun desugaring orqali.
Joda-Time-dan java.time-ga migratsiya — kutubxona mualliflari imkon qadar xavfsiz va bashorat qilinadigan qilishga harakat qilgan jarayon. Sinflarning aksariyati to'g'ridan-to'g'ri analoglarga ega: DateTime → ZonedDateTime, LocalDate → LocalDate (nom mos keladi), LocalTime → LocalTime, DateTimeZone → ZoneId, Period → Period, Duration → Duration. Asosiy o'zgarishlar obyektlarni yaratish usuli va metod nomlariga tegishli — masalan, `now.toDate()` o'rniga `Date.from(instant)`, `DateTime.now()` esa `ZonedDateTime.now()` bilan almashtiriladi.
Migratsiyani Joda-Time ni yupqa abstraksiya qatlamida izolyatsiya qilish bilan boshlash tavsiya etiladi — bu kutubxonani bosqichma-bosqich, butun kod bazasiga ta'sir qilmasdan almashtirish imkonini beradi. Birinchi qadamda odatda LocalDate va LocalTime bilan ishlash almashtiriladi — bu sinflar kutubxonalar o'rtasida eng kam farqlarga ega. Ikkinchi bosqichda DateTime (ZonedDateTime-ga) va vaqt mintaqalari migratsiya qilinadi. Uchinchi bosqichda Interval, Period va Duration almashtiriladi — bu erda yoz vaqtini hisobga olgan holda xatti-harakatni diqqat bilan tekshirish kerak. Migratsiya tugagandan so'ng, Joda-Time loyihaning bog'liqliklaridan butunlay o'chiriladi.
// Joda-Time (migratsiyadan oldin)
val dateTime = DateTime.now(DateTimeZone.forID("Europe/Moscow"))
val formatted = dateTime.toString("dd.MM.yyyy")
val plusDay = dateTime.plusDays(1)
// java.time (migratsiyadan keyin)
val zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))
val formatted2 = zonedDateTime.format(
DateTimeFormatter.ofPattern("dd.MM.yyyy")
)
val plusDay2 = zonedDateTime.plusDays(1)
Joda-Time-dan java.time-ga o'tishni soddalashtiradigan bir nechta vositalar mavjud. OpenRewrite (by Moderne) org.openrewrite.java.migrate.JodaTimeToJavaTime retsepti orqali avtomatik migratsiyani qo'llab-quvvatlaydi — u dastur mantig'ini saqlab, sinflar, metodlar va importlarni almashtiradi. Gradle loyihalari uchun de.fayard.refreshVersions plagini ham migratsiya qoidalarini o'z ichiga oladi. Qo'lda migratsiyani IDEA bilan o'tkazish eng oson: Java Time Migration Assistant plagini Joda-Time chaqiruvlarini ajratib ko'rsatadi va java.time-da tegishli almashtirishlarni taklif qiladi, bu jarayonni qo'lda almashtirish bilan solishtirganda 2–3 marta tezlashtiradi.
Joda-Time bilan Android ilovalarida amaliy ish misollarini ko'rib chiqaylik. Kutubxona mahalliy standartlarga muvofiq sanalarni formatlash, foydalanuvchi yoshini hisoblash, hodisalarning davomiyligini aniqlash va ikki sana o'rtasidagi intervallarni hisoblash vazifalari uchun ayniqsa foydalidir. Barcha misollar o'zgarmas obyektlardan foydalanadi — har bir chaqiruv yangi nusxani qaytaradi, asl obyekt esa o'zgarishsiz qoladi.
// Foydalanuvchi yoshini hisoblash
val birthDate = LocalDate.parse("1990-05-15")
val today = LocalDate.now()
val age = Years.yearsBetween(birthDate, today).getYears()
// yosh == 36
// Foydalanuvchi lokali bilan formatlash
val dateTime = DateTime.now()
val formatter = DateTimeFormat.forStyle("MM").withLocale(Locale.getDefault())
val localized = formatter.print(dateTime)
Joda-Time dagi intervallar vaqt kesimlarining kesishishini tekshirish, qoplanishlarni hisoblash va eng yaqin hodisani topish vazifalarini samarali hal qilish imkonini beradi. Masalan, kalendar ilovasini ishlab chiqishda yangi hodisaning mavjud hodisalar bilan kesishishini tekshirish mumkin. Interval sinfi contains, overlaps, gap va abuts operatsiyalarini qo'llab-quvvatlaydi — oxirgisi intervallarning chegaralar bilan tegishini ko'rsatadi. Ikki moment o'rtasidagi muddatni o'lchash uchun millisekund aniqligi bilan Duration ishlatiladi.
// Interval qoplanishini tekshirish
Interval meeting1 = new Interval(
new DateTime(2026, 7, 21, 10, 0),
new DateTime(2026, 7, 21, 11, 0)
);
Interval meeting2 = new Interval(
new DateTime(2026, 7, 21, 10, 30),
new DateTime(2026, 7, 21, 11, 30)
);
boolean overlaps = meeting1.overlaps(meeting2); // true
Duration gap = meeting1.gap(meeting2); // null (bo'shliq yo'q)
Tez-tez beriladigan savollar
Joda-Time — Java 8 chiqishidan oldin yaratilgan, Java-da sanalar va vaqt bilan ishlash uchun kutubxona. U java.util.Date va java.util.Calendar-ning kamchiliklarini tuzatdi: o'zgaruvchanlik, oylarning 0 dan raqamlanishi, vaqt mintaqalarining to'liq qo'llab-quvvatlanmasligi va ip-xavfsiz bo'lmagan formatlash.
Java.time (JSR-310) — xuddi shu muallif tomonidan ishlab chiqilgan Joda-Time-ning vorisi. Asosiy farqlar: java.time Java 8+ standart kutubxonasiga kiritilgan, yanada izchil nomlash tizimidan foydalanadi, muqobil kalendar tizimlarini qo'llab-quvvatlaydi va UTC vaqti bilan ishlash uchun Instant sinfini o'z ichiga oladi.
Yo'q, yangi loyihalar uchun java.time dan foydalanish tavsiya etiladi. Joda-Time 2014-yildan beri qo'llab-quvvatlash rejimida va endi yangi imkoniyatlarni olmaydi. Android API 26+ uchun java-time mahalliy mavjud, eski versiyalar uchun esa desugaring — API 19+ qurilmalarda java.time dan foydalanish imkonini beruvchi mexanizm qo'llaniladi.
Migratsiya bosqichma-bosqich amalga oshiriladi: Joda-Time-ni abstraksiyalarda izolyatsiya qiling, avval LocalDate va LocalTime-ni, keyin DateTime → ZonedDateTime-ni, va oxirgi bosqichda — Period, Duration va Interval-ni almashtiring. OpenRewrite vositasi JodaTimeToJavaTime retsepti orqali avtomatik migratsiyani qo'llab-quvvatlaydi, bu jarayonni 2–3 marta tezlashtiradi.
DateTime → ZonedDateTime, LocalDate → LocalDate (mos keladi), LocalTime → LocalTime, LocalDateTime → LocalDateTime, DateTimeZone → ZoneId, Interval → to'g'ridan-to'g'ri analogi yo'q (Instant + Duration kombinatsiyasi ishlatiladi), Period → Period, Duration → Duration. Metod nomlari ham yaqin: plusDays, minusMonths, withZone ikkala kutubxonada ham mavjud.
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.