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
  • RT @OMGFactsTECH: The first two video games copyrighted in the U.S. were Asteroids and Lunar Lander in 1980
    October 1, 2014 at 3:21 PM
  • Expansion update: remodel construction & electrical done; mudding, painting & carpet to go. Can't wait for our bigger team rooms!
    October 1, 2014 at 1:14 PM
  • Reddit's ExplainLikeImFive has good discussion brewing - "How does a coding language get 'coded' in the first place?" http://t.co/tXj3dISHCi
    September 30, 2014 at 11:10 AM
  • Each dev language has its own way of working with random number generation. See how #JavaScript & #Java stack up: http://t.co/QENl4kGVIs
    September 30, 2014 at 10:43 AM
  • .@TheGrisExplores: there's a new comment on your Dependency Injection Options for Java blog post - http://t.co/vs897t7bHd (Just FYI :-) )
    September 29, 2014 at 1:48 PM
  • Don't miss Vince Pendergrass' first post on the Keyhole blog - Don’t just randomize, truly randomize! http://t.co/QENl4kGVIs #cryptography
    September 29, 2014 at 9:57 AM
  • .@manohart Thank you for reading! Post author Alok Pandey has answered your question here - http://t.co/Uhn9Bv9L1a
    September 26, 2014 at 11:33 AM
  • Tech Night is now! @zachagardner & @lukewpatterson are presenting to the team on #Docker Code-Along style. Great discussions to be had!
    September 25, 2014 at 5:15 PM
  • Neat - A #JavaScript promise is an I.O.U. to return a value in the future. Here's a quick overview of promises: http://t.co/6wCz9aP4Qn
    September 25, 2014 at 11:35 AM
  • A huge welcome to Matthew Brown who joins the Keyhole team today!
    September 24, 2014 at 4:30 PM
  • RT @darrellpratt: A Journey From Require.js to Browserify http://t.co/t6N7Db1I4A
    September 24, 2014 at 11:54 AM
  • Creating a UI Designer for Quick Development - http://t.co/pNrayNFs5T http://t.co/hvqOaD6Wfq
    September 24, 2014 at 10:40 AM
  • We are under construction! Knocking down walls & expanding our offices in Leawood, KS this week. http://t.co/ph6JElh8lr
    September 23, 2014 at 9:46 AM
  • Did you know? Today in 1986 it was ruled that computer code is protected under copyright law - http://t.co/mCmWPvKOBE
    September 22, 2014 at 4:30 PM
  • Don't miss Alok Pandey's very first post on the Keyhole blog - Creating a UI Designer for Quick Development http://t.co/dWYMCOO3rf
    September 22, 2014 at 2:43 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/mf1F3eIDY3
    September 21, 2014 at 5:15 PM
  • Check out a quick intro to Functional Reactive Programing and #JavaScript - http://t.co/4LSt6aPJvG
    September 20, 2014 at 11:15 AM
  • In Part 2 of our series on creating your own #Java annotations, learn about processing them with the Reflection API - http://t.co/E1lr3RmjI7
    September 19, 2014 at 12:15 PM
  • The life of a Keyhole consultant - A Delicate Balance: It’s What We Do http://t.co/ToRpWY3aix Blog as true today as the day it was written.
    September 19, 2014 at 9:50 AM
  • 7 Things You Can Do to Become a Better Developer - http://t.co/llPNMUN8nQ
    September 19, 2014 at 8:43 AM
Keyhole Software
8900 State Line Road, Suite 455
Leawood, KS 66206
ph: 877-521-7769
© 2014 Keyhole Software, LLC. All rights reserved.