BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Date4j - A Minimalistic Library for Handling Dates

Date4j - A Minimalistic Library for Handling Dates

This item in japanese

Bookmarks

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.

Rate this Article

Adoption
Style

BT