Dealing with TimeZones in Java without Joda Time
I’ve begun working on a java SDK for nexmo’s API. Thanks to the wonders of timezones I had a crappy time (the 24 hour cold I currently have didn’t help).
Mark works in the UK and I work on East Coast time. Only because of our team’s remote nature did we discover that we had failing tests due to timezones. Cue multiple discussions of “I don’t know what’s wrong, it works on my machine!” After noticing the bug we realized the CI didn’t catch it because Travis CI sets the timezones on its containers to UTC time and the bug only appeared off of UTC time.
We want to minimize dependencies so my colleague Mark and I agreed to not use Joda Time. We were definitely asking for trouble. Here’s what I learned today while debugging our tests:
-
java.util.Date.toString()
will always print in your timezone -
java.util.Calendar.toDate()
will always print in your timezone -
java.util.Date
doesn’t have the concepts of a timezone, onlyjava.util.Calendar
does - One way to make the tests pass is use
java.util.TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
but that’s a cop-out. Definitely a code smell in your tests! - I miss Joda Time
Something to note is that the problem with debugging tests is that when the tests fail it prints out the dates as a String. Printing out the dates converts it to your timezone.
What’s the moral of the story? …I’m not sure. I still don’t have the tests passing yet.
Update: We got the tests passing! How you might ask? Well when we instantiated a new GregorianCalendar
we were missing two key pieces. A TimeZone and a Millisecond. Thus I learned that you need explicitly set the TimeZone and the millisecond of a new java.util.GregorianCalendar
or else it defaults to your current time/timezone.