ThreeTen: The Ultimate Future of Java Date/Time…In Progress

by on November 22, 2011 8:06 am

My last article was entitled Joda-Time: The Future of Java Date/Time and I was pleased to see a lot of discussion on the topic. However, I may well have inappropriately named the article. I suppose I should have called it “Joda-Time: A Glimpse of the Future of Java Date/Time” or “Joda-Time: A Step on the Way to JSR-310.” Thus the title of this article, and the inspiration for this follow-up.

The main reason I had focused on Joda-Time instead of JSR-310 (colloquially known as ThreeTen) is because Joda-Time is a mature framework that has many examples and published tutorials, examples, etc. Additionally, many people are using Joda-Time.  Also, the basic concepts in Joda-Time will translate (at least partially) into ThreeTen, so it’s a worthwhile investment of time.

I won’t discuss all the changes and improvements in ThreeTen; that’s covered well on the ThreeTen Project website.

One of the things you will notice upon reviewing the website is that ThreeTen still is in Alpha. Examples are not as plentiful, and the methods and classes still are in flux. In fact, the author of Joda-Time and the lead on ThreeTen recommends against its use in his comment on this Stack Overflow discussion. Additionally, on this very long discussion thread at The Server Side, Colebourne notes that the JDBC date classes are under the control of the JDBC group and are not part of ThreeTen. Also, he notes that there is a greater need for data conversion methods between date/time objects.

So armed with that research, I thought it might be good to revisit my previous article’s examples, noting how they would change with ThreeTen, and get an idea of the readiness of the ThreeTen project. So I headed on over to the ThreeTen Project and downloaded version 0.6.3– which I was surprised to see was nearly a year old!

Reviewing the code, I noted that the classes were similarly named to the Joda-Time classes but existed in the javax.time package. I also noticed that three Java classes: java.util.Calendar, java.util.GregorianCalendar, and java.util.Date all had been changed for tighter integration.

In my previous article on Joda-Time, I showed how complex it was to use the current Java date/time classes to create a date object representing the Apollo 11 moon landing, which occurred on July 20, 1969 at 4:17 pm US/Eastern time. Here’s how it was done in Joda-Time, first creating the date object in Eastern US time and then converting it to Central US time:

DateTimeFormatter fmtDateTime = DateTimeFormat.forPattern("M/dd/yyyy h:mm a");
fmtDateTime = fmtDateTime.withZone(DateTimeZone.forID("US/Eastern"));
DateTime dateTimeWithZone = new DateTime(fmtDateTime.parseDateTime("7/20/1969 4:17 pm"));
System.out.println("DateTimeString = " + dateTimeString + " --> JodaDateTime FORMATTED W TZ = " + dateTimeWithZone.toString("MMMM dd, yyyy h:m z"));
DateTime dateTimeCentral = new DateTime(dateTimeWithZone, DateTimeZone.forID("US/Central"));
System.out.println("DateTimeString = 7/20/1969 4:17 PM --> JodaDateTime FORMATTED W Central TZ = " + dateTimeCentral.toString("MMMM dd, yyyy h:m z));

Now you can see the output:

DateTimeString = 7/20/1969 4:17 pm --> JodaDateTime FORMATTED W TZ = July 20, 1969 4:17 EDT
DateTimeString = 7/20/1969 4:17 pm -->; JodaDateTime FORMATTED W Central TZ = July 20, 1969 3:17 CDT

Now let’s look at how to create the date object representing the Eastern US time zone using ThreeTen:

DateTimeFormatter dtzf = new DateTimeFormatterBuilder().appendPattern("M/dd/yyyy h:mm a z").toFormatter();
ZonedDateTime dateTimeWithZone = ZonedDateTime.parse("7/20/1969 4:17 pm EST", dtzf);

Whoa. Can’t parse the date string:

Text '7/20/1969 4:17 pm EDT' could not be parsed at index 15

Okay, definitely either I have the formatting string wrong or there’s a problem with the formatter. Let’s try this again using the standard ISO-8601 date format:

ateTimeFormatter dtzf = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ss.SSS Z").toFormatter();
ZonedDateTime dateTimeWithZone = ZonedDateTime.parse("1969-07-20T16:17:00.000 -0500", dtzf);
System.out.println("ZonedDateTime String = 7/20/1969 4:17 PM --> 310ZonedDateTime FORMATTED W TZ = " + dateTimeWithZone.toString(dtzf));

It seems that the code above also throws an exception… it is able to parse the string into an object, but isn’t able to create the object we are asking for.

Text '1969-07-20T16:17:00.000 -0500' could not be parsed into ZonedDateTime but was parsed to {ISO.OffsetDateTime=1969-07-20T16:17-05:00}

I dug into the code and saw that in the CalendricalMerger class, the ISOChronology singleton is used to merge the date created into the date we want; however, there is a note on that item: “TODO better?”. Debugging through the source, I found that the merge() method dropped all the way to the end without properly merging the object.

In fact, I ran into several issues parsing dates into the appropriate object. This definitely is an area that needs work in ThreeTen, especially if you are using it to parse user input. Definitely some work to be done here, as noted by the developers, since I expected standard formats to provide similar results to Joda-Time.

So to continue with this example, I used the following code:

 ZonedDateTime dateTimeWithZone = ZonedDateTime.of(1969, MonthOfYear.JULY, 20, 16, 17, 0, 0,    javax.time.calendar.TimeZone.of("US/Eastern"));
DateTimeFormatter dtzf = new DateTimeFormatterBuilder().appendPattern("M/dd/yyyy h:mm a z").toFormatter();
System.out.println("ZonedDateTime String = 7/20/1969 4:17 PM --> 310ZonedDateTime FORMATTED W TZ = " + dateTimeWithZone.toString(dtzf));
ZonedDateTime centralDateTimeZone = dateTimeWithZone.toOffsetDateTime().atZoneSameInstant(javax.time.calendar.TimeZone.of("US/Central"));
System.out.println("ZonedDateTime EASTERN String = 7/20/1969 4:17 PM --> 310ZonedDateTime CENTRAL FORMATTED W TZ = " + centralDateTimeZone.toString(dtzf));

This gave us some odd results:

ZonedDateTime String = 7/20/1969 4:17 PM --> 310ZonedDateTime FORMATTED W TZ = 7/20/1969 3:17 PM America/Indianapolis
ZonedDateTime EASTERN String = 7/20/1969 4:17 PM --> 310ZonedDateTime CENTRAL FORMATTED W TZ = 7/20/1969 2:17 PM America/Chicago

It looks to me that the formatter adjusts the time to my current time zone (US/Central) instead of the expected US/Eastern time zone. So I tried a different formatter:

ZonedDateTime dateTimeWithZone = ZonedDateTime.of(1969, MonthOfYear.JULY, 20, 16, 17, 0, 0, javax.time.calendar.TimeZone.of("US/Eastern"));
DateTimeFormatter dtzf = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd'T'HH:mm:ss.SSS Z").toFormatter();
System.out.println("ZonedDateTime String = 7/20/1969 4:17 PM --> 310ZonedDateTime FORMATTED W TZ = " + dateTimeWithZone.toString(dtzf));
ZonedDateTime centralDateTimeZone = dateTimeWithZone.toOffsetDateTime().atZoneSameInstant(javax.time.calendar.TimeZone.of("US/Central"));
System.out.println("ZonedDateTime EASTERN String = 7/20/1969 4:17 PM --> 310ZonedDateTime CENTRAL FORMATTED W TZ = " + centralDateTimeZone.toString(dtzf));

And now the times appear as expected:

ZonedDateTime String = 7/20/1969 4:17 PM --> 310ZonedDateTime FORMATTED W TZ = 1969-07-20T16:17:00.000 US/Eastern
ZonedDateTime EASTERN String = 7/20/1969 4:17 PM --> 310ZonedDateTime CENTRAL FORMATTED W TZ = 1969-07-20T15:17:00.000 US/Central

This looks like another issue with the formatter. While I like the approach and usability of the newer ThreeTen objects, this concerns me and seems to be a good reason why this library, while promising, still is not production ready.

My last article indicated an example of Joda-Time working with Daylight Savings Time. ThreeTen works exactly the same in this regard (with the exception of parsing a String to a date), using ZonedDateTime as the replacement for the DateTime object and a slightly different exception:

ZonedDateTime dateSpringForward = null;
try {
    dateSpringForward = ZonedDateTime.of(2011, MonthOfYear.MARCH, 13, 2, 5, 0, 0,
    javax.time.calendar.TimeZone.of("America/Chicago"));
    System.out.println("Spring forward date = " + dateSpringForward);
    } catch (CalendricalException e) {
    System.err.println("Hey! Time doesn't exist! --> " + e.getMessage());
}

Which produces the following output, as expected:

Hey! Time doesn't exist! -->; Local time 2011-03-13T02:05 does not exist in time-zone America/Chicago due to a gap in the local time-line

One thing that I loved having in Joda-Time was the DateMidnight object…but that currently does not exist in ThreeTen.

In the future I’d like to evaluate and compare the date manipulation features of ThreeTen and see how they compare and improve on Joda-Time. However, at this time, based on the examples provided, it seems that ThreeTen has some important improvements– and some significant flaws. Thus, while this framework holds promise for the future, it definitely is not ready for use at this time.

Not that Stephen Colebourne didn’t already tell you that, though.

— David Kieras, asktheteam@keyholesoftware.com

  • Share:

2 Responses to “ThreeTen: The Ultimate Future of Java Date/Time…In Progress”

  1. I think the 310 offers some interesting changes and the idea of tying a TimeZone to a Date object is in fact a good idea for some things (such as the Apollo landing which should justifiably be EDT). However, I am still baffled at the issues people make about the use of Dates in Java. Here’s my counter code to your original article:

    public static void main(String[] args)
    {
    TimeZone local = TimeZone.getDefault();
    TimeZone eastern = TimeZone.getTimeZone(“US/Eastern”);
    TimeZone utc = TimeZone.getTimeZone(“UTC”);
    SimpleDateFormat sdf = new SimpleDateFormat(“MMMMM dd yyyy hh:mm a Z z”);
    /* July 20, 1969 at 4:17 pm US/Eastern */
    Calendar apollo = Calendar.getInstance(eastern);
    apollo.set(1969, Calendar.JULY, 20, 16, 17);

    sdf.setTimeZone(utc);
    System.out.println(sdf.format(apollo.getTime()));
    sdf.setTimeZone(eastern);
    System.out.println(sdf.format(apollo.getTime()));
    sdf.setTimeZone(local);
    System.out.println(sdf.format(apollo.getTime()));
    }

    //OUTPUT
    July 20 1969 08:17 PM +0000 UTC
    July 20 1969 04:17 PM -0400 EDT
    July 20 1969 04:17 PM -0400 EDT //America/New York EST (It’s November)

    What’s interesting about 310 is the possibility of tying a TimeZone to a Date. That would be very useful in a number of situations. However, the real problem with date issues in Java can be solved with the simple use of RTFM.
    Calendar.setTimeZone() <– this alters input, not the output. Thus, set the time zone of the format, not the calendar and your original code works as expected.

    These are good articles and they draw a lot of focus to a serious area of confusion around dates. The API is not as clear as it could be and JSR 310 may help address that. JodaTime is another attempt (I don't see an advantage, but it is cleaner in some aspects and clean code is important).

    In short, perhaps the future of DateTime needs to be:

    public class ZoneDateTime
    {
    private TimeZone zone;
    private Date date;
    }

    Its nice to see a formal specification that would allow "global" times.

Leave a Reply

Things Twitter is Talking About
  • We send out our free monthly tech newsletter tomorrow - dev tips/articles via email. Not on the list? Sign up: http://t.co/h8kpjn419s
    September 16, 2014 at 2:58 PM
  • Want to chuckle? If programming languages were vehicles -http://t.co/quqHsUFCtR #funny
    September 16, 2014 at 11:41 AM
  • In Part 2 of our series on creating your own annotations, learn about processing #Java annotations using Reflection: http://t.co/DJZvQuarkc
    September 16, 2014 at 9:06 AM
  • Don't miss @jhackett01's newest post on the Keyhole blog - Processing #Java Annotations Using Reflection: http://t.co/E1lr3RmjI7
    September 15, 2014 at 12:02 PM
  • We're pretty excited - Keyhole's #BikeMS team raised 158% of their fundraising goal to benefit @MidAmericaMS. Plus, they had a great ride!
    September 15, 2014 at 10:38 AM
  • A huge welcome to David Kelly (@rheomatic) who officially joins the Keyhole team today! :-)
    September 15, 2014 at 10:00 AM
  • Sending warm thoughts to @eastlack, @cdesalvo, @wdpitt & all participating in #BikeMS this AM. Thanks for helping in the fight against MS!
    September 13, 2014 at 8:10 AM
  • .@rheomatic We are so excited to have you joining the team! Welcome :-)
    September 12, 2014 at 4:11 PM
  • As the official holiday is a Saturday, we're celebrating today! Happy (early) #ProgrammersDay to you! http://t.co/1CvUfrzytE
    September 12, 2014 at 1:55 PM
  • Tomorrow @cdesalvo, @eastlack, & @wdpitt are riding #BikeMS to benefit @MidAmericaMS. You can get involved, too - http://t.co/9boQwEUxth
    September 12, 2014 at 11:00 AM
  • RT @AgileDevs: 5 tips for great code reviews http://t.co/9PdbtEv0z8
    September 11, 2014 at 2:53 PM
  • The BEMs of Structuring #CSS - http://t.co/159suYtfx6 A quick introduction to the Block Element Modifier methodology.
    September 10, 2014 at 2:49 PM
  • A huge welcome to Joseph Post (@jsphpst) who has joined the Keyhole team this week!
    September 10, 2014 at 9:52 AM
  • @TheGrisExplores Absolutely, and thanks for the compliment! Here's an article that you might find helpful, too - http://t.co/7oxpaohCS1
    September 9, 2014 at 2:22 PM
  • Express.js seems to be the top pick! MT @TheGrisExplores: "what's your fave server-side MVC framework for NodeJS when SPA is not an option?"
    September 9, 2014 at 1:56 PM
  • RT @TheGrisExplores: Yo @KeyholeSoftware dudes and dudettes: what is your favorite server-side MVC framework for NodeJS when SPA is not an …
    September 9, 2014 at 1:15 PM
  • There is a new post on the Keyhole blog by @brianletteri - The BEMs of Structuring CSS: http://t.co/159suYtfx6
    September 9, 2014 at 12:12 PM
  • Know a bright grad? We're looking for a business support / recruiting representative to join our team in Kansas City: http://t.co/GDvFVmoMF9
    September 8, 2014 at 11:31 AM
  • A huge welcome to @jeremygard who joins the Keyhole team today!
    September 8, 2014 at 8:40 AM
  • 8 tips to help you code for maintainability so the next developer doesn't hate you (which we think is important) - http://t.co/Aoe931WLzb
    September 5, 2014 at 2:40 PM
Keyhole Software
8900 State Line Road, Suite 455
Leawood, KS 66206
ph: 877-521-7769
© 2014 Keyhole Software, LLC. All rights reserved.