Joda-Time: vad är det, datumbibliotek och ersättning för Java 8

Författare: IT Sectr Publicerad: 2026-07-14 Lästid: 10 min

Joda-Time — ett bibliotek för att arbeta med datum och tid i Java, skapat av Stephen Colebourne som ett alternativ till de obekväma java.util.Date och java.util.Calendar. Före lanseringen av Java 8 var detta bibliotek de facto standard för att arbeta med datum inom industriell utveckling, inklusive Android-applikationer. Enligt Oracle Java Magazine (2023) migrerade över 60% av projekten från Joda-Time till java.time inom två år efter lanseringen av Android API 26.

Huvudpunkter

  • Joda-Time — bibliotek för att arbeta med datum och tid, föregångare till java.time i Java 8
  • Immutable-klasser — DateTime, LocalDate, LocalTime, LocalDateTime garanterar trådsäkerhet
  • Tidszonsstöd — inbyggd tidszonsdatabas med automatiska uppdateringar
  • Migrering — java.time (JSR-310) ersätter helt Joda-Time, bibliotekets författare rekommenderar övergången
  • Android — Joda-Time fungerar från API 1, men för Android 8+ (API 26) är java.time att föredra

Vad är Joda-Time?

Joda-Time — är ett bibliotek med öppen källkod (Apache 2.0) som tillhandahåller en högkvalitativ ersättning för klasserna java.util.Date och java.util.Calendar i programmeringsspråket Java. Projektet grundades av Stephen Colebourne år 2004 som svar på de många problemen med standard-API:erna för att arbeta med datum, inklusive mutbarhet, komplex formatering och begränsat stöd för tidszoner. Biblioteket fick stor spridning i Java-communityt och användes av tusentals projekt, inklusive stora enterprise-system och Android-applikationer, där de inbyggda verktygen för att arbeta med datum var särskilt obekväma. Sedan lanseringen av Java 8 2014 och introduktionen av paketet java.time (JSR-310) har biblioteket förts över till underhållsläge — nya funktioner läggs inte till och den befintliga funktionaliteten täcks fullt ut av det nya API:et.

Bibliotekets arkitektur

Joda-Time är byggd på principen om oföränderlighet: varje datum- eller tidsobjekt kan efter skapandet inte ändras. Varje operation — att lägga till en dag, ändra en månad, ställa in en tidszon — returnerar ett nytt objekt, medan originalet förblir oförändrat. Detta tillvägagångssätt eliminerar helt klassen av fel som är förknippade med oavsiktlig modifiering av objekt, vilket var karakteristiskt för mutabla java.util.Date och java.util.Calendar. Den oföränderliga designen gör också biblioteket trådsäkert utan extra synkronisering.

Grundläggande klasser i Joda-Time

Biblioteket tillhandahåller flera huvudklasser för olika scenarier: DateTime — fullständigt datum och tid med tidszon, LocalDate — endast datum utan tid, LocalTime — endast tid utan datum, LocalDateTime — datum och tid utan koppling till zon. Dessutom ingår klasser för att arbeta med intervall (Interval), perioder (Period) och varaktigheter (Duration), som gör det möjligt att beräkna skillnaden mellan två tidpunkter i olika måttenheter. Varje klass implementerar gränssnittet ReadableInstant eller ReadablePartial för enhetlig bearbetning.

Historien om Joda-Time

Problemet med standard-API:erna för datum i Java var känt sedan plattformens början. Klasserna java.util.Date och java.util.Calendar hade fundamentala brister: månader numrerades från 0, Date representerade samtidigt både datum och tid, Calendar var mutabel och krävde komplex konfiguration. Formatering via SimpleDateFormat var inte trådsäker — i flertrådade applikationer ledde detta till felaktig tolkning av datum. Stephen Colebourne, som arbetade på projekt med intensiv användning av datum, beslutade sig för att skapa ett alternativ som skulle lösa alla dessa problem.

Enligt en intervju på InfoQ (2014) testade Colebourne Joda-Time i industriella projekt i mer än ett år före den första offentliga lanseringen. Den första versionen släpptes 2004 och väckte omedelbart communityts uppmärksamhet. År 2010 hade biblioteket blivit ett standardberoende i de flesta Java-projekt, inklusive ramverk som Spring och Hibernate. Framgången för Joda-Time påverkade direkt specifikationen JSR-310 (Date and Time API), som inkluderades i Java 8 — och författaren till specifikationen var samme Stephen Colebourne.

Inverkan på Java-ekosystemet

Joda-Time löste inte bara datumproblemet — det förändrade synsättet på API-design i Java. Konceptet med oföränderliga värdeobjekt, som demonstrerades av biblioteket, antogs som standard i Java 8 för alla nya API:er. Dessutom visade Joda-Times popularitet Oracle att communityt inte är berett att tolerera standardbibliotek av låg kvalitet — efter Joda-Time omarbetades API:erna för att arbeta med filer (NIO.2), tid (java.time) och valfria värden (Optional) i Java.

Joda-Time-bibliotekets viktigaste funktioner

Joda-Time erbjuder en uppsättning funktioner som före Java 8 inte var tillgängliga i standardbiblioteket. De främsta fördelarna inkluderar stöd för över 200 tidszoner med automatisk hantering av sommartid, ett rikt formaterings-API med mönster och språkinställningar, samt beräkning av perioder mellan datum i olika enheter — år, månader, dagar, timmar. Särskild uppmärksamhet förtjänar intervall-systemet: Interval (mellanrum mellan två tidpunkter), Period (skillnad i kalenderenheter) och Duration (exakt varaktighet i millisekunder).

Formatering och tolkning

Klassen DateTimeFormatter i Joda-Time tillhandahåller trådsäker formatering av datum — till skillnad från java.text.SimpleDateFormat. Formaterare kan skapas via mönster (t.ex. "yyyy-MM-dd HH:mm:ss") eller via stilar (SHORT, MEDIUM, LONG, FULL) för lokaliserad utdata. Biblioteket stöder också cachning av formaterare, vilket snabbar upp arbetet i högt belastade applikationer. Tolkning av datum från strängar görs med kontroll av strikthet — ofullständiga eller felaktiga datum kan tillåtas eller förbjudas.

Intervall och beräkningar

En av styrkorna hos Joda-Time är arbetet med tidsintervall. Klassen Interval representerar ett exakt tidssegment mellan två tidpunkter (Instant) och stöder operationer för skärning, förening och medlemskapskontroll. Period, till skillnad från Interval, arbetar med kalenderenheter — till exempel är skillnaden mellan 1 mars och 1 april exakt 1 månad, även om det varaktighetsmässigt kan vara 28–31 dagar. Duration representerar den exakta varaktigheten i millisekunder utan koppling till kalender och är lämplig för att mäta exekveringstid för operationer.

java
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(); // dagar = 7

Interval interval = new Interval(now, nextWeek);
boolean contains = interval.contains(now); // sant

Jämförelse mellan Joda-Time och java.time

Paketet java.time (JSR-310) utvecklades av samma författare — Stephen Colebourne — och absorberade de bästa idéerna från Joda-Time med hänsyn till tio års driftserfarenhet. Båda API:erna använder oföränderliga klasser, stöder tidszoner och erbjuder en rik uppsättning operationer. Men java.time är fullt integrerat i Java-standardbiblioteket, kräver inga externa beroenden och använder ett mer konsekvent namngivningssystem: Instant istället för ReadableInstant, LocalDate istället för LocalDate (namnet behållet), ZonedDateTime istället för DateTime.

EgenskapJoda-Timejava.time
Lanseringsår20042014 (Java 8)
StatusUnderhåll (maintenance)Aktiv utveckling
Grundläggande datum/tidDateTimeZonedDateTime
Endast datumLocalDateLocalDate
OföränderlighetJaJa
FormateringDateTimeFormatterDateTimeFormatter
DatumskillnadPeriod / DurationPeriod / Duration

Viktigaste skillnaderna

java.time korrigerar flera arkitektoniska beslut i Joda-Time. För det första har förvirringen mellan metoder som returnerar null och saknade värden eliminerats i java.time — istället används Optional. För det andra har stöd för alternativa kalendersystem (japanska, thailändska, islamiska) lagts till via gränssnittet Chronology. För det tredje innehåller java.time klassen Instant för att arbeta med tidpunkter i UTC utan koppling till kalender — detta förenklar integrationen med nätverksprotokoll och databaser. För Android rekommenderas användning av java.time från och med API 26 (Android 8.0) eller via desugaring för äldre versioner.

Migrering från Joda-Time till java.time

Migrering från Joda-Time till java.time — en process som bibliotekets författare försökte göra så säker och förutsägbar som möjligt. De flesta klasser har direkta motsvarigheter: DateTime → ZonedDateTime, LocalDate → LocalDate (namnet överensstämmer), LocalTime → LocalTime, DateTimeZone → ZoneId, Period → Period, Duration → Duration. De viktigaste förändringarna rör sättet att skapa objekt och metodnamn — till exempel används `Date.from(instant)` istället för `now.toDate()`, och `DateTime.now()` ersätts av `ZonedDateTime.now()`.

Steg-för-steg migreringsstrategi

Det rekommenderas att påbörja migreringen genom att isolera Joda-Time i ett tunt abstraktionslager — detta möjliggör byte av biblioteket stegvis utan att påverka hela kodbasen. Det första steget är vanligtvis att ersätta arbetet med LocalDate och LocalTime — dessa klasser har minst skillnader mellan biblioteken. I den andra fasen migreras DateTime (till ZonedDateTime) och tidszoner. I den tredje fasen ersätts Interval, Period och Duration — här måste beteendet noggrant kontrolleras med hänsyn till sommartid. Efter slutförd migrering tas Joda-Time bort helt från projektets beroenden.

kotlin
// Joda-Time (före migrering)
val dateTime = DateTime.now(DateTimeZone.forID("Europe/Moscow"))
val formatted = dateTime.toString("dd.MM.yyyy")
val plusDay = dateTime.plusDays(1)

// java.time (efter migrering)
val zonedDateTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"))
val formatted2 = zonedDateTime.format(
    DateTimeFormatter.ofPattern("dd.MM.yyyy")
)
val plusDay2 = zonedDateTime.plusDays(1)

Verktyg för migrering

Det finns flera verktyg som förenklar övergången från Joda-Time till java.time. OpenRewrite (by Moderne) stöder automatisk migrering via receptet org.openrewrite.java.migrate.JodaTimeToJavaTime — det ersätter klasser, metoder och importer samtidigt som programlogiken bevaras. För Gradle-projekt innehåller insticksprogrammet de.fayard.refreshVersions också migreringsregler. Manuellt är migrering enklast att utföra med IDEA: insticksprogrammet Java Time Migration Assistant markerar Joda-Time-anrop och föreslår motsvarande ersättningar i java.time, vilket snabbar upp processen 2–3 gånger jämfört med manuell ersättning.

Kodexempel Joda-Time

Låt oss titta på praktiska exempel på att arbeta med Joda-Time i Android-applikationer. Biblioteket är särskilt användbart för uppgifter som att formatera datum enligt lokala standarder, beräkna användarens ålder, bestämma varaktigheten av händelser och beräkna intervall mellan två datum. Alla exempel använder oföränderliga objekt — varje anrop returnerar en ny instans medan originalobjektet förblir oförändrat.

kotlin
// Beräkna användarens ålder
val birthDate = LocalDate.parse("1990-05-15")
val today = LocalDate.now()
val age = Years.yearsBetween(birthDate, today).getYears()
// ålder == 36

// Formatera med användarens locale
val dateTime = DateTime.now()
val formatter = DateTimeFormat.forStyle("MM").withLocale(Locale.getDefault())
val localized = formatter.print(dateTime)

Arbeta med intervall

Intervall i Joda-Time gör det möjligt att effektivt lösa uppgifter som att kontrollera överlappning av tidssegment, beräkna överlappningar och hitta den närmaste händelsen. Till exempel vid utveckling av en kalenderapplikation kan man kontrollera om en ny händelse överlappar med befintliga händelser. Klassen Interval stöder operationerna contains, overlaps, gap och abuts — den sistnämnda visar om intervallerna vidrör varandra vid gränserna. För att mäta varaktigheten mellan två tidpunkter används Duration med millisekunders precision.

java
// Kontrollera intervallöverlappning
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); // sant
Duration gap = meeting1.gap(meeting2); // null (inget gap)

Vanliga frågor

Vad är Joda-Time och vad används det till?

Joda-Time — ett bibliotek för att arbeta med datum och tid i Java, skapat före lanseringen av Java 8. Det åtgärdade bristerna i java.util.Date och java.util.Calendar: mutbarhet, numrering av månader från 0, brist på fullt stöd för tidszoner och icke-trådsäker formatering.

Vad skiljer Joda-Time från java.time?

Java.time (JSR-310) — efterföljaren till Joda-Time, utvecklad av samma författare. De viktigaste skillnaderna: java.time är inbyggt i standardbiblioteket för Java 8+, använder ett mer konsekvent namngivningssystem, stöder alternativa kalendersystem och innehåller klassen Instant för att arbeta med UTC-tid.

Är det värt att använda Joda-Time i nya projekt?

Nej, för nya projekt rekommenderas att använda java.time. Joda-Time har varit i underhållsläge sedan 2014 och får inte längre nya funktioner. För Android med API 26+ är java.time tillgängligt inbyggt, och för äldre versioner används desugaring — en mekanism som möjliggör användning av java.time på enheter med API 19+.

Hur migrerar man kod från Joda-Time till java.time?

Migrering utförs i faser: isolera Joda-Time i abstraktioner, ersätt först LocalDate och LocalTime, sedan DateTime → ZonedDateTime, och i den sista fasen — Period, Duration och Interval. Verktyget OpenRewrite stöder automatisk migrering via receptet JodaTimeToJavaTime, vilket snabbar upp processen 2–3 gånger.

Vilka Joda-Time-klasser motsvarar java.time?

DateTime → ZonedDateTime, LocalDate → LocalDate (överensstämmer), LocalTime → LocalTime, LocalDateTime → LocalDateTime, DateTimeZone → ZoneId, Interval → har ingen direkt motsvarighet (kombination av Instant + Duration används), Period → Period, Duration → Duration. Metodnamnen är också liknande: plusDays, minusMonths, withZone finns tillgängliga i båda biblioteken.

Sammanfattning

  • Joda-Time — datum- och tidsbibliotek för Java, som blev standard före lanseringen av Java 8 och direkt påverkade specifikationen JSR-310
  • Oföränderlig design — alla Joda-Time-klasser är oföränderliga, vilket garanterar trådsäkerhet och förhindrar oavsiktliga mutationer av objekt
  • Nyckelklasser — DateTime, LocalDate, LocalTime, LocalDateTime, Period, Duration och Interval täcker alla scenarier för att arbeta med datum och tid
  • Tidszonsstöd — inbyggd databas med över 200 zoner med automatisk hantering av sommartid och uppdateringar
  • Migrering till java.time — rekommenderas för alla projekt; utförs stegvis med hjälp av OpenRewrite och inbyggda IDE-verktyg
  • Android-kompatibilitet — Joda-Time fungerar från API 1, men för API 26+ är java.time att föredra, tillgängligt via desugaring på äldre versioner
  • Historisk betydelse — Joda-Time förändrade synsättet på API-design i Java och visade communityt fördelarna med oföränderliga värdeobjekt

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också