Skip to content

Java/Daylight Savings Time Fun!

Last week I finally figured out this little date problem that has been plaguing some of my applications at work. Basically the symptom was under some circumstances credit card expiration dates would be sent to the processor one month earlier than it was supposed to be. While digging through logs I noticed the expiration date was serialized to ‘2010-11-01T06:00:00.000Z’. The reason this is interesting is because the servers are in the Mountain time zone, so the date should have been serialized to ‘2010-11-01T07:00:00.000Z’. So I wrote a this little example program:

    public static void main(String[] args) throws ParseException
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/yyyy");
        TimeZone mst = TimeZone.getTimeZone("MST");
        TimeZone gmt = TimeZone.getTimeZone("GMT");


        Date date = dateFormat.parse("11/2010");
        System.out.println("date: " + date);

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 6);
        System.out.println("cal: " + cal.getTime());
        System.out.println("cal.formatted: " + dateFormat.format(cal.getTime()));
        System.out.println("cal.month: " + cal.get(Calendar.MONTH));
        System.out.println("cal.year: " + cal.get(Calendar.YEAR));

This is the output I got when I ran it on my Mac, using Java 1.4 (j2sdk 1.4.2_09):

date: Mon Nov 01 00:00:00 MST 2010
cal: Sun Oct 31 23:00:00 MST 2010
cal.formatted: 10/2010
cal.month: 10
cal.year: 2010
ERROR!!! Expected inputDate: 11/2010, received: 10/2010

No matter what I did, Java would always localize the date to my current time zone. I happen to know a Java Champion (besides the one that has commented on my blog), and his first solution was to switch all our machines to UTC — which is easier said than done. I then sent him the program, and he said it worked. I asked him to send me the output, and this is what he sent me:

date: Mon Nov 01 00:00:00 MDT 2010
cal: Mon Nov 01 00:00:00 MDT 2010
cal.formatted: 11/2010
cal.month: 10
cal.year: 2010

He had run it on Java 1.5. I didn’t realize it at the time, but the MDT is the clue. Some bit of Googling about Java and Daylight Savings Time turned up an article on called U.S. Daylight Saving Time Changes in 2007. Mystery solved.

The machine parsing and creating the date, running on j2sdk1.4.2_11, properly parsed the date, and recognized it as being in Daylight Savings Time (GMT-6). However the web service receiving that date was running on j2sdk1.4.2_05, treats the date as GMT-7, thus effectively pushing the month back by one.

Lessons Learned:

  • Don’t use a java.util.Date object when all you need is the month and year components
  • Use new versions of Java (which is tough on a Mac since Apple has only released j2sdk 1.4.2_09)

Posted in Java, Software Development.

0 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

Some HTML is OK

or, reply to this post via trackback.