Differences Between Java 8 Date Time API (Java.Time) and Joda-Time

Differences between Java 8 Date Time API (java.time) and Joda-Time

Common features

a) Both libraries use immutable types. Joda-Time also offers additional mutable types like MutableDateTime.

b) Furthermore: Both libraries are inspired by the design study "TimeAndMoney" from Eric Evans or ideas from Martin Fowler about domain driven style so they strive more or less for a fluent programming style (although not always perfect ;-)).

c) With both libraries we get a real calendar date type (called LocalDate), a real wall time type (called LocalTime) and the composition (called LocalDateTime). That is a very big win compared with old java.util.Calendar and java.util.Date.

d) Both libraries use a method-centric approach meaning they encourage the user to use getDayOfYear() instead of get(DAY_OF_YEAR). This causes a lot of extra methods compared with java.util.Calendar (although latter is not type-safe at all due to excessive use of ints).

Performance

See the other answer by @OO7 pointing to the analysis of Mikhail Vorontsov although point 3 (exception catching) is probably obsolete - see this JDK-bug. The different performance (which is in general favour of JSR-310) is mainly due to the fact that the internal implementation of Joda-Time always use a machine-time-like long-primitive (in milliseconds).

Null

Joda-Time often use NULL as default for system timezone, default locale, current timestamp etc. while JSR-310 almost always rejects NULL values.

Precision

JSR-310 handles nanosecond precision while Joda-Time is limited to millisecond precision.

Supported fields:

An overview about supported fields in Java-8 (JSR-310) is given by some classes in the temporal-package (for example ChronoField and WeekFields) while Joda-Time is rather weak on this area - see DateTimeFieldType. The biggest lack of Joda-Time is here the absence of localized week-related fields. A common feature of both field implementation design is that both are based on values of type long (no other types, not even enums).

Enum

JSR-310 offers enums like DayOfWeek or Month while Joda-Time does not offer this because it was mainly developed in years 2002-2004 before Java 5.

Zone API

a) JSR-310 offers more timezone features than Joda-Time. Latter is not able to yield a programmatical access to the history of timezone offset transitions while JSR-310 is capable to do this.

b) For your information: JSR-310 has moved its internal timezone repository to a new location and a different format. The old library folder lib/zi does not exist any more.

Adjuster vs. Property

JSR-310 has introduced the TemporalAdjuster-interface as a formalized way to externalize temporal calculations and manipulations, especially for library or framework-writers this is a nice and relative easy way to embed new extensions of JSR-310 (a kind of equivalent to static helper classes for former java.util.Date).

For most users however, this feature has very limited value because the burden to write code is still with the user. Built-in solutions based on the new TemporalAdjuster-concept are not so many, there is currently only the helper class TemporalAdjusters with a limited set of manipulations (and the enums Month or other temporal types).

Joda-Time offers a field-package but practice has shown evidence that new field implementations are very hard to code. On the other side Joda-Time offers so-called properties which make some manipulations much easier and more elegant than in JSR-310, for example property.withMaximumValue().

Calendar systems

JSR-310 offers 4 extra calendar systems. The most interesting one is Umalqura (used in Saudi Arabia). The other 3 are: Minguo (Taiwan), Japanese (only the modern calendar since 1871!) and ThaiBuddhist (only correct after 1940).

Joda-Time offers an Islamic calendar based on calculatory base - not a sighting-based calendar like Umalqura. Thai-Buddhist is also offered by Joda-Time in a similar form, Minguo and the japanese one not. Otherwise Joda-Time offers coptic and ethiopic calendar, too (but without any support for internationalization).

More interesting for Europeans: Joda-Time also offers a Gregorian, Julian and mixed-gregorian-julian calendar. However, the practical value for real historical calculations is limited because important features like different year starts in date history are not supported at all (the same criticism is valid for old java.util.GregorianCalendar).

Other calendars like Hebrew or Persian or Hindu are completely missing in both libraries.

Epoch days

JSR-310 has the class JulianFields while Joda-Time (version 2.0) offers some helper methods in the class DateTimeUtils.

Clocks

JSR-310 has no interface (a design mistake) but an abstract class java.time.Clock which can be used for any clock dependency injection. Joda-Time offers the interface MillisProvider and some helper methods in DateTimeUtils instead. So this way Joda-Time is also capable of supporting test-driven models with different clocks (mocking etc.).

Duration arithmetic

Both libraries support the calculation of time distances in one or more temporal units. However, when handling single-unit-durations the JSR-310-style is obviously nicer (and long-based instead of using int):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Time => int days = DAYS.daysBetween(date1, date2).getDays();

Handling of multiple-unit-durations are also different. Even the calculation results can differ - see this closed Joda-Time issue. While JSR-310 use a very simple and limited approach to use just the classes Period (duration based on years, months and days) and Duration (based on seconds and nanoseconds), Joda-Time uses a more sophisticated way using the class PeriodType in order to control in which units a duration (Joda-Time call it "Period") shall be expressed. While the PeriodType-API is somehow awkward to use a similar way is not offered by JSR-310 at all. Especially it is not yet possible in JSR-310 to define mixed date and time durations (based on days and hours for example). So be warned if it comes to migration from one library to another. The libraries in discussion are incompatible - despite of partially same class names.

Intervals

JSR-310 does not support this feature while Joda-Time has limited support. See also this SO-answer.

Formatting and Parsing

Best way to compare both libraries is to view the equal-named classes DateTimeFormatterBuilder (JSR-310) and DateTimeFormatterBuilder (Joda-Time). The JSR-310-variant is a little bit more powerful (can also handle any kind of TemporalField provided the field implementor has managed to code some extension points like resolve()). Most important difference is however - in my opinion:

JSR-310 can much better parse timezone names (format pattern symbol z) while Joda-Time could not do this at all in its earlier versions and now only in a very limited way.

Another advantage of JSR-310 is support for standalone month names which is important in languages like Russian or Polish etc. Joda-Time has no access to such resources - not even on Java-8 platforms.

The pattern syntax in JSR-310 is also more flexible than in Joda-Time, allows for optional sections (using square brackets), is more orientated towards CLDR-standard and offers padding (letter symbol p) and more fields.

Otherwise it should be noted that Joda-Time can format durations using PeriodFormatter. JSR-310 cannot do this.


Hope this overview helps. All the gathered information is mainly there due to my efforts and investigations how to design and implement a better date-and-time library (nothing is perfect).

Update from 2015-06-24:

Meanwhile I have found the time to write and publish a tabular overview for different time libraries in Java. The tables also contain a comparison between Joda-Time v2.8.1 and Java-8 (JSR-310). It is more detailed than this post.

Is Joda Time deprecated with java 8 Date and Time API? (java.time)

The official statement of the author of Joda-time himself is to migrate as soon as Java-8 is available. See also this citation from the website:

Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).

So the short answer to your question is: YES (deprecated). However, keep in mind that some features like Joda-Interval or PeriodType or PeriodFormatter are not available in Java-8 so you have to write your own partially ugly workarounds, see also my SO-post about differences between Joda-Time and JSR-310.

Side remarks about the future of both libraries:

What does "finished" means in this context?

Well, you can compare the Joda-issue 254 with my small discussion on Twitter. I think people should rather set down their expectations to any major enhancement of Joda-Time. Please also consider that the future development resources regarding Joda-Time are limited (lack of manpower). And let's be honest: Most releases since Joda-Time in year 2008 rather have the character of bugfix releases (with the exception of 2.0).

On the other side: The innovation speed of JSR-310 will probably not be very high, too (because it is already big, and because Oracle is here the decisive player and a date-time-library is in general not considered as the central cornerstone of any Java-release). So there is always some space left for an external library in the future to supply missing features, for example (in alphabetical order):

  • Threeten-Extra (as the favourite of Basil Bourque, see his comment)
  • Time4J (my own extension, interoperability issue solved in summer 2015)

Joda Time and Java8 Time difference

Joda-Time and Java 8 java.time.* have different algorithms for determining the number of months between.

java.time.* only declares a month has passed once the day-of-month is greater (or in the next month). From 2017-01-29 to 2017-02-28 it is clear that the second day-of-month (28) is less than the first (29) so a month has not yet been completed.

Joda-Time declares a month has passed because adding 1 month to 2017-01-29 will yield 2017-02-28.

Both are plausible algorithms, but I believe the java.time.* algorithm to be more in tune with what people expect (which is why I chose a different algorithm when writing java.time.*).

Differences between java.util.Date and Joda Time APIs

Java's standard date and time classes (mainly java.util.Date and java.util.Calendar) have limited functionality and have a number of design problems. The fact that many of the constructors and methods of java.util.Date are deprecated is one indication of this.

Joda Time has a much better thought out API than what's available in Java's standard library. There are classes for timestamps with or without a timezone, classes for holding only a date (year, month, day) or only a time of day, classes for periods, durations and intervals, it supports the ISO 8601 format (which is the standard format in XML documents) and much more.

I'd use Joda Time as my standard date and time library in any project - there really is no reason to use java.util.Date and java.util.Calendar.

Note that in a future release of Java, a new date and time API will most likely be included that's going to look a lot like what's currently available in Joda Time; see Project ThreeTen.

Also see Why Joda Time? on the home page of the Joda Time project.

Also, I've seen conflicting info about whether Joda Time is part of the standard API. Is it standard or not?

No, it isn't part of the standard API.

Update (copied from the comments):

Java 8 is out now, and it has a new date and time API which is similar to Joda Time (see the package java.time). If you're using Java 8, then please use the new date & time API.

Good way for Java Date comparison without time

The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API.

  • For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7.
  • If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Learn about the modern date-time API from Trail: Date Time.

LocalDate uses JVM's timezone by default

Whenever timezone is involved, make sure to specify the same while creating an instance of LocalDate. A LocalDate uses JVM's timezone by default and you should never compare a LocalDate from one timezone to that of another without converting both of them in the same timezone (the recommended one is UTC). Same is the case with LocalDateTime. Instead of using LocalDate, you should do all processing with objects which have both date and time (e.g. LocalDateTime) and if required you can derive the LocalDate from them.

Also, the java.util.Date object simply represents the number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT (or UTC). When you print an object of java.util.Date, its toString method returns the date-time in the JVM's timezone, calculated from this milliseconds value.

Therefore, if you are deriving expiryDate from a java.util.Date object, it is essentially date-time in UTC.

You can convert now-in-PST and expiryDate into java.time.Instant and compare them. A java.time.Instant is an instantaneous point on the UTC time-line.

Demo using the modern date-time API:

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;

public class Main {
public static void main(String[] args) {
LocalDateTime nowInPST = LocalDateTime.now(ZoneId.of("America/Los_Angeles"));
System.out.println(nowInPST);

// Convert it to date in UTC
Instant nowInPSTConvertedToInstant = nowInPST.atZone(ZoneId.of("America/Los_Angeles"))
.withZoneSameInstant(ZoneId.of("Etc/UTC"))
.toInstant();

// Some java.util.Date
Calendar calendar = Calendar.getInstance();
calendar.set(2020, 0, 10, 10, 10, 10);
Date date = calendar.getTime();
Instant expiry = date.toInstant();

System.out.println(nowInPSTConvertedToInstant.isBefore(expiry));
}
}

Output:

2021-01-17T10:58:38.490041
false

Note: Check the following notice at the Home Page of Joda-Time

Joda-Time is the de facto standard date and time library for Java
prior to Java SE 8. Users are now asked to migrate to java.time
(JSR-310).

Simplify your expression

The following statement

boolean notExpired = expiryDate.isEqual(now) || expiryDate.isAfter(now);

can be simplified as

boolean notExpired = !expiryDate.isBefore(now);

Calculating the difference between two Java date instances

The JDK Date API is horribly broken unfortunately. I recommend using Joda Time library.

Joda Time has a concept of time Interval:

Interval interval = new Interval(oldTime, new Instant());

EDIT: By the way, Joda has two concepts: Interval for representing an interval of time between two time instants (represent time between 8am and 10am), and a Duration that represents a length of time without the actual time boundaries (e.g. represent two hours!)

If you only care about time comparisions, most Date implementations (including the JDK one) implements Comparable interface which allows you to use the Comparable.compareTo()

Equivalent to jodatime Interval in Java 8 Date and Time API

No way, the Joda class Interval does not exist in JSR-310. The concepts of Duration, Period etc. denotes temporal amounts without being bound to fixed points in time while an interval has a fixed start and fixed end on the timeline.

By the way, this question is not new and a duplicate. On the other SO-link you can also find a similar answer direct from JodaTime-project-leader.

migrate from Joda time library to Java time (Java 8)

Most questions about conversion should be handled by my blog on the topic.

Q1a:
There is no point in creating a Joda-Time object only to change back to java.util.Date. However, the method should probbaly take Instant or ZonedDateTime:

Instant instant = Instant.now();
doSomething(instant); // method changed to take Instant

Note that Instant is the closest match to java.util.Date.

Q1b:
This case involves a time-zone, so should use ZonedDateTime.

ZonedDateTime java8DateTime = ZonedDateTime.now();  // uses ZoneId.systemDefault()
ZonedDateTime java8DateTimeInPast = java8DateTime.minusSeconds(60);
doSomething(java8DateTimeInPast.toInstant());

Again, this assumes that doSomething is changed to take an Instant.

The key to using java.time properly is to think about what data type is correct for each piece of data.

  • Just a date? Then use LocalDate
  • Just a time? Then use LocalTime
  • Date, time and time-zone? Then use ZonedDateTime
  • Just a timestamp with no other info? Then use Instant
  • A network date-time format with offset (not zone)? Then use OffsetDateTime.

What are the differences between Joda LocalDate and java.util's Date?

I think the Joda Time Website explains it all very well.

Joda-Time has been created to radically change date and time handling in Java.
The JDK classes Date and Calendar are very badly designed, have had numerous bugs
and have odd performance effects.
Here are some of our reasons for developing and using Joda-Time:

  • Easy to Use.
    Calendar makes accessing 'normal' dates difficult, due to the lack of simple methods.
    Joda-Time has straightforward field accessors such as
    getYear() or getDayOfWeek().
  • Easy to Extend.
    The JDK supports multiple calendar systems via subclasses of Calendar.
    This is clunky, and in practice it is very difficult to write another calendar system.
    Joda-Time supports multiple calendar systems via a pluggable system based on the
    Chronology class.
  • Comprehensive Feature Set.
    The library is intended to provide all the functionality that is required for date-time
    calculations. It already provides out-of-the-box features, such as support for oddball
    date formats, which are difficult to replicate with the JDK.
  • Up-to-date Time Zone calculations.
    The time zone implementation is based on
    the public tz database, which is
    updated several times a year. New Joda-Time releases incorporate all changes
    made to this database. Should the changes be needed earlier,
    manually updating the zone data is easy.
  • Calendar support.
    The library currently provides 8 calendar systems. More will be added in the future.
  • Easy interoperability.
    The library internally uses a millisecond instant which is identical to the JDK and similar
    to other common time representations. This makes interoperability easy, and Joda-Time comes
    with out-of-the-box JDK interoperability.
  • Better Performance Characteristics.
    Calendar has strange performance characteristics as it recalculates fields at unexpected moments.
    Joda-Time does only the minimal calculation for the field that is being accessed.
  • Good Test Coverage.
    Joda-Time has a comprehensive set of developer tests, providing assurance of the library's quality.
  • Complete Documentation.
    There is a full User Guide which provides an overview and covers
    common usage scenarios. The javadoc
    is extremely detailed and covers the rest of the API.
  • Maturity.
    The library has been under active development since 2002.
    Although it continues to be improved with the addition of new features and
    bug-fixes, it is a mature and reliable code base.
    A number of related projects are now available.
  • Open Source.
    Joda-Time is licenced under the business friendly Apache License Version 2.0.



Related Topics



Leave a reply



Submit