Joda-Time: What It Is, the Date Library, and Replacement with Java 8

Author: IT Sectr Published: 2026-07-14 Reading time: 10 min

Joda-Time is a library for working with dates and times in Java, created by Stephen Colebourne as an alternative to the cumbersome java.util.Date and java.util.Calendar. Before the release of Java 8, this library was the de facto standard for date handling in industrial development, including Android applications. According to Oracle Java Magazine (2023), over 60% of projects migrated from Joda-Time to java.time within two years after the release of Android API 26.

Key Takeaways

  • Joda-Time is a library for working with dates and times, the predecessor of java.time in Java 8
  • Immutable classes — DateTime, LocalDate, LocalTime, LocalDateTime ensure thread safety
  • Timezone support — built-in timezone database with automatic updates
  • Migration — java.time (JSR-310) fully replaces Joda-Time, the library authors recommend the transition
  • Android — Joda-Time works from API 1, but for Android 8+ (API 26) java.time is preferred

What Is Joda-Time?

Joda-Time is an open-source library (Apache 2.0) that provides a quality replacement for the java.util.Date and java.util.Calendar classes in the Java language. The project was founded by Stephen Colebourne in 2004 in response to numerous problems with the standard date and time APIs, including mutability, formatting complexity, and limited timezone support. The library gained widespread adoption in the Java community and was used by thousands of projects, including large enterprise systems and Android applications, where the built-in date handling tools were especially inconvenient. Since the release of Java 8 in 2014 and the introduction of the java.time package (JSR-310), the library has been placed in maintenance mode — new features are not being added, and the existing functionality is fully covered by the new API.

Library Architecture

Joda-Time is built on the principle of immutability: each date or time object cannot be changed after creation. Any operation — adding a day, changing a month, setting a timezone — returns a new object, leaving the original unchanged. This approach completely eliminates the class of errors associated with unintentional object modification that were characteristic of mutable java.util.Date and java.util.Calendar. The immutable design also makes the library thread-safe without additional synchronization.

Core Joda-Time Classes

The library provides several main classes for different scenarios: DateTime — full date and time with timezone, LocalDate — date only without time, LocalTime — time only without date, LocalDateTime — date and time without timezone binding. Additionally, classes for working with intervals (Interval), periods (Period), and durations (Duration) are included, allowing you to calculate the difference between two points in time in various units of measurement. Each class implements the ReadableInstant or ReadablePartial interface for uniform handling.

History of Joda-Time

The problem with the standard Java date APIs had been known since the platform’s inception. The java.util.Date and java.util.Calendar classes had fundamental flaws: months were numbered starting from 0, Date simultaneously represented both date and time, Calendar was mutable and required complex configuration. Formatting through SimpleDateFormat was not thread-safe — in multithreaded applications this led to incorrect date parsing. Stephen Colebourne, working on projects with intensive date usage, decided to create an alternative that would fix all these problems.

According to an interview on InfoQ (2014), Colebourne tested Joda-Time in production projects for over a year before the first public release. The first version was released in 2004 and immediately attracted the community’s attention. By 2010, the library had become a standard dependency in most Java projects, including frameworks such as Spring and Hibernate. The success of Joda-Time directly influenced the JSR-310 specification (Date and Time API), which was included in Java 8 — with the same Stephen Colebourne as the specification lead.

Impact on the Java Ecosystem

Joda-Time didn’t just solve the date problem — it changed the approach to API design in Java. The concept of immutable value objects, demonstrated by the library, was adopted as a standard in Java 8 for all new APIs. Moreover, the popularity of Joda-Time showed Oracle that the community was not willing to tolerate low-quality standard libraries — after Joda-Time, Java APIs for file handling (NIO.2), time (java.time), and optional values (Optional) were reworked.

Key Features of the Joda-Time Library

Joda-Time provides a set of features that were unavailable in the standard library before Java 8. Key advantages include support for 200+ timezones with automatic daylight saving time handling, a rich formatting API with patterns and locales, as well as period calculations between dates in various units — years, months, days, hours. Of particular note is the interval system: Interval (a span between two instants), Period (difference in calendar units), and Duration (exact length in milliseconds).

Formatting and Parsing

The DateTimeFormatter class in Joda-Time provides thread-safe date formatting — unlike java.text.SimpleDateFormat. Formatters can be created through patterns (e.g., “yyyy-MM-dd HH:mm:ss”) or through styles (SHORT, MEDIUM, LONG, FULL) for localized output. The library also supports formatter caching, which speeds up performance in high-load applications. Parsing dates from strings is performed with strictness control — you can allow or disallow incomplete or incorrect dates.

Intervals and Calculations

One of the strong points of Joda-Time is working with time intervals. The Interval class represents an exact time span between two instants and supports intersection, union, and containment check operations. Period, unlike Interval, operates in calendar units — for example, the difference between March 1 and April 1 is exactly 1 month, although in duration it could be 28–31 days. Duration, on the other hand, represents an exact length in milliseconds without calendar binding and is suitable for measuring operation execution time.

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

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

Joda-Time vs java.time Comparison

The java.time package (JSR-310) was developed by the same author — Stephen Colebourne — and incorporated the best ideas of Joda-Time with ten years of operational experience. Both APIs use immutable classes, support timezones, and provide a rich set of operations. However, java.time is fully integrated into the Java standard library, requires no external dependencies, and uses a more consistent naming system: Instant instead of ReadableInstant, LocalDate instead of LocalDate (name preserved), ZonedDateTime instead of DateTime.

CharacteristicJoda-Timejava.time
Release year20042014 (Java 8)
StatusMaintenanceActive development
Base date/timeDateTimeZonedDateTime
Date onlyLocalDateLocalDate
ImmutabilityYesYes
FormattingDateTimeFormatterDateTimeFormatter
Date differencePeriod / DurationPeriod / Duration

Key Differences

java.time fixes several architectural decisions of Joda-Time. First, java.time eliminates the confusion between methods returning null and missing values — using Optional instead. Second, support for alternative calendar systems (Japanese, Thai, Islamic) has been added through the Chronology interface. Third, java.time includes the Instant class for working with UTC time instants without calendar binding — this simplifies integration with network protocols and databases. For Android, it is recommended to use java.time starting from API 26 (Android 8.0) or through desugaring for older versions.

Migrating from Joda-Time to java.time

Migrating from Joda-Time to java.time is a process that the library authors tried to make as safe and predictable as possible. Most classes have direct counterparts: DateTime → ZonedDateTime, LocalDate → LocalDate (name matches), LocalTime → LocalTime, DateTimeZone → ZoneId, Period → Period, Duration → Duration. The main changes involve the way objects are created and method names — for example, instead of `now.toDate()`, use `Date.from(instant)`, and `DateTime.now()` is replaced with `ZonedDateTime.now()`.

Step-by-Step Migration Strategy

It is recommended to start the migration by isolating Joda-Time in a thin abstraction layer — this allows replacing the library incrementally without touching the entire codebase. The first step is usually to replace work with LocalDate and LocalTime — these classes have the fewest differences between libraries. The second stage migrates DateTime (to ZonedDateTime) and timezones. The third stage replaces Interval, Period, and Duration — here you need to carefully check daylight saving time behavior. After completing the migration, Joda-Time is completely removed from the project dependencies.

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

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

Migration Tools

Several utilities exist to simplify the transition from Joda-Time to java.time. OpenRewrite (by Moderne) supports automatic migration through the recipe org.openrewrite.java.migrate.JodaTimeToJavaTime — it replaces classes, methods, and imports while preserving program logic. For Gradle projects, the de.fayard.refreshVersions plugin also includes migration rules. Manually, migration is easiest to perform with IDEA: the Java Time Migration Assistant plugin highlights Joda-Time calls and suggests corresponding java.time replacements, speeding up the process by 2–3 times compared to manual replacement.

Joda-Time Code Examples

Let’s look at practical examples of working with Joda-Time in Android applications. The library is especially useful for formatting dates according to local standards, calculating user age, determining event duration, and calculating intervals between two dates. All examples use immutable objects — each call returns a new instance, while the original object remains unchanged.

kotlin
// Calculate user age
val birthDate = LocalDate.parse("1990-05-15")
val today = LocalDate.now()
val age = Years.yearsBetween(birthDate, today).getYears()
// age == 36

// Format with user locale
val dateTime = DateTime.now()
val formatter = DateTimeFormat.forStyle("MM").withLocale(Locale.getDefault())
val localized = formatter.print(dateTime)

Working with Intervals

Intervals in Joda-Time allow you to efficiently solve tasks such as checking time interval overlaps, calculating intersections, and finding the nearest event. For example, when developing a calendar application, you can check whether a new event overlaps with existing ones. The Interval class supports contains, overlaps, gap, and abuts operations — the latter shows whether intervals touch at their boundaries. Duration is used to measure the length between two instants with millisecond precision.

java
// Check interval overlap
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 (no gap)

Frequently Asked Questions

What is Joda-Time and why is it needed?

Joda-Time is a library for working with dates and times in Java, created before the release of Java 8. It fixed the shortcomings of java.util.Date and java.util.Calendar: mutability, zero-based month numbering, lack of full timezone support, and non-thread-safe formatting.

How is Joda-Time different from java.time?

Java.time (JSR-310) is the successor of Joda-Time, developed by the same author. The main differences: java.time is built into the Java 8+ standard library, uses a more consistent naming system, supports alternative calendar systems, and includes the Instant class for working with UTC time.

Should I use Joda-Time in new projects?

No, for new projects it is recommended to use java.time. Joda-Time has been in maintenance mode since 2014 and no longer receives new features. For Android with API 26+, java.time is available natively, and for older versions desugaring is used — a mechanism that allows using java.time on devices with API 19+.

How to migrate code from Joda-Time to java.time?

Migration is performed step by step: isolate Joda-Time in abstractions, replace LocalDate and LocalTime first, then DateTime → ZonedDateTime, and finally Period, Duration, and Interval. The OpenRewrite tool supports automatic migration through the JodaTimeToJavaTime recipe, speeding up the process by 2–3 times.

Which Joda-Time classes correspond to java.time?

DateTime → ZonedDateTime, LocalDate → LocalDate (matches), LocalTime → LocalTime, LocalDateTime → LocalDateTime, DateTimeZone → ZoneId, Interval → no direct equivalent (a combination of Instant + Duration is used), Period → Period, Duration → Duration. Method names are also similar: plusDays, minusMonths, withZone are available in both libraries.

Summary

  • Joda-Time is a date and time library for Java that became the standard before Java 8 and directly influenced the JSR-310 specification
  • Immutable design — all Joda-Time classes are immutable, ensuring thread safety and preventing accidental object mutations
  • Key classes — DateTime, LocalDate, LocalTime, LocalDateTime, Period, Duration, and Interval cover all date and time scenarios
  • Timezone support — built-in database of 200+ timezones with automatic daylight saving time handling and updates
  • Migration to java.time — recommended for all projects; performed incrementally using OpenRewrite tools and built-in IDE features
  • Android compatibility — Joda-Time works from API 1, but for API 26+ java.time is preferred, available through desugaring on older versions
  • Historical significance — Joda-Time changed the approach to API design in Java and demonstrated the benefits of immutable value objects to the community

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also