Joda-Time — isang library para sa pagtatrabaho sa mga petsa at oras sa Java, na nilikha ni Stephen Colebourne bilang alternatibo sa hindi maginhawang java.util.Date at java.util.Calendar. Bago ang paglabas ng Java 8, ang library na ito ang de facto na pamantayan para sa pagtatrabaho sa mga petsa sa pang-industriyang pag-unlad, kabilang ang mga Android application. Ayon sa Oracle Java Magazine (2023), higit sa 60% ng mga proyekto ang lumipat mula Joda-Time patungong java.time sa loob ng dalawang taon pagkatapos ng paglabas ng Android API 26.
Mga Pangunahing Punto
Joda-Time — ay isang open-source library (Apache 2.0) na nagbibigay ng de-kalidad na kapalit para sa mga klase ng java.util.Date at java.util.Calendar sa wikang Java. Ang proyekto ay itinatag ni Stephen Colebourne noong 2004 bilang tugon sa maraming problema ng mga karaniwang API para sa pagtatrabaho sa mga petsa, kabilang ang mutability, pagiging kumplikado ng pag-format, at limitadong suporta sa timezone. Ang library ay naging malawak sa komunidad ng Java at ginamit ng libu-libong proyekto, kabilang ang malalaking enterprise system at Android application, kung saan ang mga built-in na tool para sa pagtatrabaho sa mga petsa ay partikular na hindi maginhawa. Mula nang ilabas ang Java 8 noong 2014 at pagdating ng package na java.time (JSR-310), ang library ay inilipat sa maintenance mode — ang mga bagong feature ay hindi idinaragdag, at ang umiiral na functionality ay ganap na nasasaklaw ng bagong API.
Ang Joda-Time ay binuo sa prinsipyo ng immutability: bawat object ng petsa o oras pagkatapos malikha ay hindi maaaring baguhin. Anumang operasyon — pagdaragdag ng araw, pagpapalit ng buwan, pagtatakda ng timezone — ay nagbabalik ng bagong object, na iniiwan ang orihinal na hindi nababago. Ang pamamaraang ito ay ganap na nag-aalis ng klase ng mga error na nauugnay sa hindi sinasadyang pagbabago ng mga object, na katangian ng mutable na java.util.Date at java.util.Calendar. Ginagawa rin ng immutable design ang library na thread-safe nang walang karagdagang synchronization.
Ang library ay nagbibigay ng ilang pangunahing klase para sa iba't ibang sitwasyon: DateTime — kumpletong petsa at oras na may timezone, LocalDate — petsa lamang nang walang oras, LocalTime — oras lamang nang walang petsa, LocalDateTime — petsa at oras nang walang koneksyon sa zone. Bukod pa rito, kasama ang mga klase para sa pagtatrabaho sa mga interval (Interval), period (Period) at duration (Duration), na nagpapahintulot sa pagkalkula ng pagkakaiba sa pagitan ng dalawang sandali ng oras sa iba't ibang unit ng pagsukat. Bawat klase ay nagpapatupad ng interface na ReadableInstant o ReadablePartial para sa pare-parehong pagproseso.
Ang problema ng mga karaniwang API ng petsa sa Java ay kilala mula pa sa simula ng platform. Ang mga klase na java.util.Date at java.util.Calendar ay may mga pangunahing kakulangan: ang mga buwan ay binilang mula 0, ang Date ay sabay na kumakatawan sa petsa at oras, ang Calendar ay mutable at nangangailangan ng kumplikadong configuration. Ang pag-format sa pamamagitan ng SimpleDateFormat ay hindi thread-safe — sa mga multi-threaded na application, ito ay humantong sa maling pag-parse ng mga petsa. Si Stephen Colebourne, habang nagtatrabaho sa mga proyektong may masinsinang paggamit ng mga petsa, ay nagpasyang lumikha ng isang alternatibo na aayusin ang lahat ng problemang ito.
Ayon sa panayam sa InfoQ (2014), sinubukan ni Colebourne ang Joda-Time sa mga proyektong pang-industriya nang higit sa isang taon bago ang unang pampublikong paglabas. Ang unang bersyon ay lumabas noong 2004 at agad na nakakuha ng atensyon ng komunidad. Pagsapit ng 2010, ang library ay naging karaniwang dependency sa karamihan ng mga proyekto ng Java, kabilang ang mga framework tulad ng Spring at Hibernate. Ang tagumpay ng Joda-Time ay direktang nakaimpluwensya sa specifikasyon na JSR-310 (Date and Time API), na isinama sa Java 8 — at ang may-akda ng specifikasyon ay ang parehong Stephen Colebourne.
Hindi lamang nalutas ng Joda-Time ang problema sa petsa — binago nito ang diskarte sa disenyo ng API sa Java. Ang konsepto ng immutable na value object na ipinakita ng library ay pinagtibay bilang pamantayan sa Java 8 para sa lahat ng bagong API. Higit pa rito, ipinakita ng kasikatan ng Joda-Time sa Oracle na ang komunidad ay hindi handang magtiis sa mababang kalidad na mga karaniwang library — pagkatapos ng Joda-Time sa Java ay muling idinisenyo ang mga API para sa pagtatrabaho sa mga file (NIO.2), oras (java.time), at opsyonal na halaga (Optional).
Ang Joda-Time ay nagbibigay ng isang hanay ng mga kakayahan na bago ang Java 8 ay hindi available sa karaniwang library. Ang mga pangunahing bentahe ay kinabibilangan ng suporta para sa higit sa 200 timezone na may awtomatikong pagproseso ng daylight saving time, mayamang API ng pag-format na may mga pattern at locale, pati na rin ang pagkalkula ng mga period sa pagitan ng mga petsa sa iba't ibang unit — taon, buwan, araw, oras. Ang sistema ng interval ay nararapat ng espesyal na pansin: Interval (agwat sa pagitan ng dalawang sandali), Period (pagkakaiba sa mga unit ng kalendaryo) at Duration (eksaktong tagal sa millisecond).
Ang klase na DateTimeFormatter sa Joda-Time ay nagbibigay ng thread-safe na pag-format ng mga petsa — hindi tulad ng java.text.SimpleDateFormat. Ang mga formatte ay maaaring gawin sa pamamagitan ng mga pattern (hal., "yyyy-MM-dd HH:mm:ss") o sa pamamagitan ng mga estilo (SHORT, MEDIUM, LONG, FULL) para sa lokalisadong output. Sinusuportahan din ng library ang caching ng mga formatte, na nagpapabilis ng trabaho sa mga application na may mataas na karga. Ang pag-parse ng mga petsa mula sa mga string ay ginagawa nang may kontrol ng kahigpitan — maaaring payagan o ipagbawal ang hindi kumpleto o hindi wastong mga petsa.
Isa sa mga malakas na aspeto ng Joda-Time ay ang pagtatrabaho sa mga agwat ng oras. Ang klase na Interval ay kumakatawan sa isang eksaktong segment ng oras sa pagitan ng dalawang sandali (Instant) at sumusuporta sa mga operasyon ng intersection, pagsasama, at pagsusuri ng kasapian. Ang Period, hindi tulad ng Interval, ay gumagana sa mga unit ng kalendaryo — halimbawa, ang pagkakaiba sa pagitan ng Marso 1 at Abril 1 ay eksaktong 1 buwan, kahit na sa tagal ay maaaring 28–31 araw. Ang Duration ay kumakatawan sa eksaktong tagal sa millisecond nang walang koneksyon sa kalendaryo at angkop para sa pagsukat ng oras ng pagpapatupad ng mga operasyon.
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(); // araw = 7
Interval interval = new Interval(now, nextWeek);
boolean contains = interval.contains(now); // totoo
Ang package na java.time (JSR-310) ay binuo ng parehong may-akda — Stephen Colebourne — at sinipsip ang pinakamahusay na mga ideya ng Joda-Time na isinasaalang-alang ang sampung taon ng karanasan sa operasyon. Ang parehong API ay gumagamit ng immutable na mga klase, sumusuporta sa timezone, at nag-aalok ng mayamang hanay ng mga operasyon. Gayunpaman, ang java.time ay ganap na isinama sa karaniwang library ng Java, hindi nangangailangan ng panlabas na dependencies, at gumagamit ng mas pare-parehong sistema ng pagpapangalan: Instant sa halip na ReadableInstant, LocalDate sa halip na LocalDate (pinanatili ang pangalan), ZonedDateTime sa halip na DateTime.
| Katangian | Joda-Time | java.time |
|---|---|---|
| Taon ng paglabas | 2004 | 2014 (Java 8) |
| Status | Pagpapanatili (maintenance) | Aktibong pag-unlad |
| Batayang petsa/oras | DateTime | ZonedDateTime |
| Petsa lamang | LocalDate | LocalDate |
| Immutability | Oo | Oo |
| Pag-format | DateTimeFormatter | DateTimeFormatter |
| Pagkakaiba ng petsa | Period / Duration | Period / Duration |
java.time ay nag-aayos ng ilang desisyong arkitektural ng Joda-Time. Una, sa java.time ang pagkalito sa pagitan ng mga method na nagbabalik ng null at nawawalang mga halaga ay inalis — sa halip ay ginagamit ang Optional. Pangalawa, idinagdag ang suporta para sa mga alternatibong sistema ng kalendaryo (Hapon, Thai, Islamiko) sa pamamagitan ng interface na Chronology. Pangatlo, ang java.time ay may kasamang klase na Instant para sa pagtatrabaho sa mga sandali ng oras sa UTC nang walang koneksyon sa kalendaryo — pinapasimple nito ang pagsasama sa mga network protocol at database. Para sa Android, inirerekomenda ang paggamit ng java.time simula sa API 26 (Android 8.0) o sa pamamagitan ng desugaring para sa mas lumang mga bersyon.
Ang migrasyon mula Joda-Time patungong java.time — isang proseso na sinikap ng mga may-akda ng library na gawing ligtas at mahuhulaan hangga't maaari. Karamihan sa mga klase ay may direktang katumbas: DateTime → ZonedDateTime, LocalDate → LocalDate (tumutugma ang pangalan), LocalTime → LocalTime, DateTimeZone → ZoneId, Period → Period, Duration → Duration. Ang mga pangunahing pagbabago ay may kinalaman sa paraan ng paggawa ng mga object at mga pangalan ng method — halimbawa, sa halip na `now.toDate()` ay ginagamit ang `Date.from(instant)`, at ang `DateTime.now()` ay pinalitan ng `ZonedDateTime.now()`.
Inirerekomenda na simulan ang migrasyon sa pamamagitan ng paghihiwalay ng Joda-Time sa isang manipis na layer ng abstraction — ito ay magbibigay-daan sa pagpapalit ng library nang paunti-unti nang hindi naaapektuhan ang buong codebase. Ang unang hakbang ay karaniwang pinapalitan ang trabaho sa LocalDate at LocalTime — ang mga klase na ito ay may pinakakaunting pagkakaiba sa pagitan ng mga library. Sa ikalawang yugto, ang DateTime (sa ZonedDateTime) at timezone ay mina-migrate. Sa ikatlong yugto, ang Interval, Period at Duration ay pinapalitan — dito kailangang maingat na suriin ang pag-uugali na isinasaalang-alang ang daylight saving time. Pagkatapos makumpleto ang migrasyon, ang Joda-Time ay ganap na tinatanggal mula sa mga dependency ng proyekto.
// Joda-Time (bago ang migrasyon)
val dateTime = DateTime.now(DateTimeZone.forID("Europe/Moscow"))
val formatted = dateTime.toString("dd.MM.yyyy")
val plusDay = dateTime.plusDays(1)
// java.time (pagkatapos ng migrasyon)
val zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))
val formatted2 = zonedDateTime.format(
DateTimeFormatter.ofPattern("dd.MM.yyyy")
)
val plusDay2 = zonedDateTime.plusDays(1)
Mayroong ilang mga utility na nagpapadali sa paglipat mula Joda-Time patungong java.time. Ang OpenRewrite (by Moderne) ay sumusuporta sa awtomatikong migrasyon sa pamamagitan ng recipe na org.openrewrite.java.migrate.JodaTimeToJavaTime — pinapalitan nito ang mga klase, method at import, na pinapanatili ang lohika ng programa. Para sa mga proyekto ng Gradle, ang plugin na de.fayard.refreshVersions ay may kasamang mga patakaran sa migrasyon. Sa manu-manong paraan, ang migrasyon ay pinakamadaling isagawa gamit ang IDEA: ang plugin na Java Time Migration Assistant ay nagha-highlight ng mga tawag sa Joda-Time at nagmumungkahi ng mga kaukulang kapalit sa java.time, na nagpapabilis ng proseso ng 2–3 beses kumpara sa manu-manong pagpapalit.
Tingnan natin ang mga praktikal na halimbawa ng pagtatrabaho sa Joda-Time sa mga Android application. Ang library ay lalong kapaki-pakinabang para sa mga gawain ng pag-format ng petsa ayon sa lokal na mga pamantayan, pagkalkula ng edad ng gumagamit, pagtukoy ng tagal ng mga kaganapan, at pagkalkula ng mga interval sa pagitan ng dalawang petsa. Lahat ng halimbawa ay gumagamit ng immutable na mga object — bawat tawag ay nagbabalik ng bagong instance, at ang orihinal na object ay nananatiling hindi nababago.
// Kalkulahin ang edad ng gumagamit
val birthDate = LocalDate.parse("1990-05-15")
val today = LocalDate.now()
val age = Years.yearsBetween(birthDate, today).getYears()
// edad == 36
// I-format gamit ang locale ng gumagamit
val dateTime = DateTime.now()
val formatter = DateTimeFormat.forStyle("MM").withLocale(Locale.getDefault())
val localized = formatter.print(dateTime)
Ang mga interval sa Joda-Time ay nagbibigay-daan sa mahusay na paglutas ng mga gawain ng pagsusuri ng intersection ng mga segment ng oras, pagkalkula ng mga overlap, at paghahanap ng pinakamalapit na kaganapan. Halimbawa, sa pagbuo ng isang application ng kalendaryo, maaaring suriin kung ang isang bagong kaganapan ay nag-o-overlap sa mga umiiral na. Ang klase na Interval ay sumusuporta sa mga operasyon na contains, overlaps, gap at abuts — ang huli ay nagpapakita kung ang mga interval ay magkadikit sa mga hangganan. Para sa pagsukat ng tagal sa pagitan ng dalawang sandali, ginagamit ang Duration na may katumpakan ng millisecond.
// Suriin ang overlap ng interval
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); // totoo
Duration gap = meeting1.gap(meeting2); // null (walang puwang)
Mga Madalas Itanong
Joda-Time — isang library para sa pagtatrabaho sa mga petsa at oras sa Java, na nilikha bago ang paglabas ng Java 8. Inayos nito ang mga kakulangan ng java.util.Date at java.util.Calendar: mutability, pagnunumero ng mga buwan mula 0, kakulangan ng buong suporta sa timezone, at hindi thread-safe na pag-format.
Ang Java.time (JSR-310) — kahalili ng Joda-Time, na binuo ng parehong may-akda. Mga pangunahing pagkakaiba: ang java.time ay naka-embed sa karaniwang library ng Java 8+, gumagamit ng mas pare-parehong sistema ng pagpapangalan, sumusuporta sa mga alternatibong sistema ng kalendaryo, at may kasamang klase na Instant para sa pagtatrabaho sa UTC time.
Hindi, para sa mga bagong proyekto inirerekomenda ang paggamit ng java.time. Ang Joda-Time ay nasa maintenance mode mula noong 2014 at hindi na tumatanggap ng mga bagong feature. Para sa Android na may API 26+, ang java.time ay available nang native, at para sa mas lumang mga bersyon ay ginagamit ang desugaring — isang mekanismo na nagpapahintulot sa paggamit ng java.time sa mga device na may API 19+.
Ang migrasyon ay isinasagawa sa mga yugto: ihiwalay ang Joda-Time sa mga abstraction, palitan muna ang LocalDate at LocalTime, pagkatapos DateTime → ZonedDateTime, at sa huling yugto — Period, Duration at Interval. Ang tool na OpenRewrite ay sumusuporta sa awtomatikong migrasyon sa pamamagitan ng recipe na JodaTimeToJavaTime, na nagpapabilis ng proseso nang 2–3 beses.
DateTime → ZonedDateTime, LocalDate → LocalDate (tumutugma), LocalTime → LocalTime, LocalDateTime → LocalDateTime, DateTimeZone → ZoneId, Interval → walang direktang katumbas (ginagamit ang kumbinasyon ng Instant + Duration), Period → Period, Duration → Duration. Ang mga pangalan ng method ay malapit din: plusDays, minusMonths, withZone ay available sa parehong library.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din