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
  • Want to write a single page app with #ExtJS? View @zachagardner's video tutorial series to get you started: http://t.co/XFYDT6YNWA
    July 29, 2014 at 3:50 PM
  • A #JavaScript promise is an I.O.U. to return a value in the future. Learn about them: http://t.co/6wCz9b7e4v
    July 29, 2014 at 1:36 PM
  • A huge welcome to John Holland who joined the Keyhole team today!
    July 28, 2014 at 4:56 PM
  • We think #JavaScript Promises are cool. Here's a good introduction from @mauget - http://t.co/6wCz9b7e4v
    July 28, 2014 at 2:19 PM
  • There's a new post on the Keyhole blog by @mauget: #JavaScript Promises Are Cool - http://t.co/6wCz9b7e4v
    July 28, 2014 at 9:52 AM
  • Thank your #Sysadmin - today is System Administrator Appreciation Day. http://t.co/LcvDNa9kPg
    July 25, 2014 at 8:05 AM
  • @rickincanada Thx for your tweet! Shoot us an email at asktheteam@keyholesoftware.com so we can set up a time to talk. Have a good day.
    July 24, 2014 at 3:33 PM
  • Never used JAXB? Check out a simple usage pattern that pairs #JAXB’s data binding capabilities with JPA - http://t.co/Ki9G04HV5e
    July 24, 2014 at 9:53 AM
  • Guess what today is? Tell An Old Joke Day - http://t.co/835ORWMX6N! So, why do programmers always confuse Halloween & Xmas? 31 Oct = 25 Dec
    July 24, 2014 at 8:45 AM
  • MT @midwestio: Posted another #midwestio talk recording to our YouTube channel: @MinaMarkham on modular CSS. Watch: http://t.co/aU3LpfUoi4
    July 24, 2014 at 8:25 AM
  • We just posted pictures from our National Hot Dog Day Lunch Cookout. Check them out - http://t.co/To06plaw1C
    July 23, 2014 at 4:14 PM
  • Good free cheat sheet - #Java Performance Optimization Refcard from @DZone: http://t.co/7vBgsmqy08
    July 23, 2014 at 10:48 AM
  • Did you know today is a holiday? It's National Hot Dog Day! We're gearing up for our team lunch hot dog cookout & can't wait to celebrate.
    July 23, 2014 at 9:43 AM
  • Check out our newest blog: #JAXB – A Newcomer’s Perspective, Part 1 http://t.co/Ki9G04HV5e
    July 22, 2014 at 1:22 PM
  • New post on the Keyhole blog by Mark Adelsberger: #JAXB – A Newcomer’s Perspective, Part 1 http://t.co/Ki9G04HV5e
    July 21, 2014 at 2:27 PM
  • If you're a Java dev, you're likely familiar with Annotations. But have you created your own #Java Annotations? Ex - http://t.co/BgCsYjxZKF
    July 18, 2014 at 12:10 PM
  • RT @gamasutra: Don't Miss: Unconventional Tips for Improving your Programming Skills http://t.co/6TFox7CKHU
    July 16, 2014 at 3:20 PM
  • We're about to send out our free monthly tech newsletter. Dev tips/articles via email. Not on the list yet? Sign up - http://t.co/F8h0NSiicZ
    July 15, 2014 at 11:57 AM
  • Have you ever tried creating your own #Java annotations? See a situation where it was beneficial - http://t.co/BgCsYjxZKF
    July 15, 2014 at 8:36 AM
  • There's a new post on the Keyhole blog by @jhackett01: Creating Your Own #Java Annotations - http://t.co/BgCsYjxZKF
    July 14, 2014 at 1:43 PM
Keyhole Software
8900 State Line Road, Suite 455
Leawood, KS 66206
ph: 877-521-7769
© 2014 Keyhole Software, LLC. All rights reserved.