The Java classes for handling dates have been mostly unchanged since JDK1.0 and suffer from well-known issues (for example January starts from 0 leading to many off-by-one bugs). A new JSR has been proposed to address those issues but it is still in Alpha version. Until it becomes stable many developers are using the Joda Time libraries which are similar (but not the same) to what the reference implementation of JSR-310 will become.
Date4j proposes another solution for handling dates in Java, but with a completely different scope from Joda Time. Here is the comparison:
Joda Time | Date4j |
---|---|
Number of classes: 140+ | Number of classes < 10 |
Mutable and immutable classes | Only immutable classes |
Focus on speed and features | Focus on simplicity and accuracy |
Supports Gregorian, Coptic, Islamic, Buddhist e.t.c calendars | Only supports Gregorian dates |
Can completely replace JDK Date classes | Works in tandem with some JDK Date classes |
Supports millisecond resolutions | Supports nanosecond resolutions |
Day "overflow" behaviour is fixed | Day "overflow" behaviour is configurable |
Aimed at general purpose date manipulation | Aimed at dates manipulated by databases |
Apache Licence 2.0 | BSD Licence |
While at first glance Date4j only offers a minimal subset of the features found in Joda, it has two major advantages that Joda does not address.
Firstly, the developers of Date4j claim that a library should never truncate your date without reason. Joda supports only millisecond accuracy and this won't change probably in the future. Several databases however have greater resolution. For example the popular PostgreSQL database supports timestamps in microseconds. Date4j can handle these dates without any loss in precision.
The second point is the date "overflow" problem i.e. adding a period to a date that rolls it over to the next month. A simple example would be adding one month to 31st of March:
DateTime dt = new DateTime("2011-03-31"); DateTime result = dt.plusMonths(1); System.out.println(result.toString());
When Joda Time runs this it will print 30th of April which may or may not be what you expected.
Recognizing this ambiguity, Date4j gives you 4 ways of addressing it:
1. | FirstDay |
2. | Last Day (Same as Joda Time) |
3. | Spill over |
4. | abort with an exception |
Here is demonstration of some of these cases (using Date4j instead of Joda):
DateTime dt1 = new DateTime("2011-03-31"); DateTime result1 = dt1.plus(0,1,0,0,0,0,DayOverflow.FirstDay); System.out.println(result1.toString()); //Prints 2011-05-01 (first of May) DateTime dt2 = new DateTime("2011-03-31"); DateTime result2 = dt2.plus(0,1,0,0,0,0,DayOverflow.LastDay); System.out.println(result2.toString()); //Prints 2011-04-30 (30th of April - same as Joda) DateTime dt3= new DateTime("2011-03-31"); DateTime result3 = dt3.plus(0,1,0,0,0,0,DayOverflow.Abort); System.out.println(result3.toString()); //Throws run time exception
This example shows the DayOverflow.Spillover option:
//Joda Time code DateTime dt = new DateTime("2010-12-31"); DateTime result = dt.plusMonths(2); System.out.println(result.toString()); //Prints 2011-02-28 (29th of February) //Date4j code DateTime dt1 = new DateTime("2010-12-31"); DateTime result1 = dt1.plus(0,2,0,0,0,0,DayOverflow.FirstDay); System.out.println(result1.toString()); //Prints 2011-03-01 (first of March) //Date4j code DateTime dt2 = new DateTime("2010-12-31"); DateTime result2 = dt2.plus(0,2,0,0,0,0,DayOverflow.LastDay); System.out.println(result2.toString()); //Prints 2011-02-28 (28th of February - Same as Joda) //Date4j code DateTime dt3= new DateTime("2010-12-31"); DateTime result3 = dt3.plus(0,2,0,0,0,0,DayOverflow.Spillover); System.out.println(result3.toString()); //Prints 2011-03-02 (2nd of March)
If your application needs high-accuracy and no loss of precision when handling database dates or you want to have maximum control on what happens with month spill overs, Date4j may be a useful library for your application. The source code is available as a direct download.
Community comments
JSR 310
by R Gransberger,
No ranges??
by Marc Stock,
Re: YADL
by John O'Hanley,
Joda comparison and DaysOverflow
by Stephen Colebourne,
Change of URL
by John O'Hanley,
JSR 310
by R Gransberger,
Your message is awaiting moderation. Thank you for participating in the discussion.
I would have prefered to see the notable features like overflow handling to be incorporated to Joda and/or JSR 310 development rather than having another framework for date/time handling.
No ranges??
by Marc Stock,
Your message is awaiting moderation. Thank you for participating in the discussion.
Any date library that doesn't offer a way to work with date ranges is seriously flawed. Am I expected to use Joda for my date range math and Date4j for everything else? There's some cool stuff in this new library but not supporting date ranges makes it a non-starter for me.
Joda comparison and DaysOverflow
by Stephen Colebourne,
Your message is awaiting moderation. Thank you for participating in the discussion.
I'm personally happy to see someone else tackle dates and times - ideas are good. This project offers a specific solution to a subset of the use cases that Joda-Time tackles, and that may be useful to some. Joda-Time used millisecond precision to be compatible with the JDK, and I think that helped its acceptance. JSR-310 uses nanosecond precsion.
JSR-310 also has the DateResolver concept, which is equivalent to DaysOverflow (but more flexible). Adding DaysOverflow/DateResolver to Joda-Time would be a relatively easy thing to do, but my focus is on 310 now, rather than Joda-Time (which is still maintained as necessary).
Stephen Colebourne, Joda-Time
Re: YADL
by John O'Hanley,
Your message is awaiting moderation. Thank you for participating in the discussion.
"Is it really not possible to collaborate with JSR0310?"
Probably not, actually. The basic designs of the two tools are very far apart. One has time zone information, and the other does not, for example.
Change of URL
by John O'Hanley,
Your message is awaiting moderation. Thank you for participating in the discussion.
The original date4j.net site has been abandoned. All source and documentation has been moved to a github repository.