Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

I've been doing quite a bit of work with time conversion recently and started to use the new 'X' pattern in Java's SimpleDateFormat class to parse ISO 8601 time zones. Initially I treated this exactly the same way as the old 'Z' pattern for RFC 822 time zones. That ended up giving me 30 minute rounding errors in some cases. Upon reading the JavaDoc closer, I found this sentece hidden among all the verboseness...
If the number of pattern letters is 1, any fraction of an hour is ignored. For example, if the pattern is "X" and the time zone is "GMT+05:30", "+05" is produced.


Ha! So the 'X' pattern has built-in precision and I needed to handle that correctly. Specifying a single 'X' would always ignore the minutes component of the time zone and I'd get an incorrect time. All I had to do was specify 'XX' to get the times to parse correctly.

Lets see some examples...

First lets see what a time zone that doesn't have a significant minutes component behaves like. In this case I am using the GMT+11 time zone.
 Time zone without minutes component
// Default time zone is UTC
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
String dtString = "20160209193500+1100";
System.out.println((new SimpleDateFormat("yyyyMMddHHmmssXX"))
.parse(dtString).toString());
System.out.println((new SimpleDateFormat("yyyyMMddHHmmssX"))
.parse(dtString).toString());


That produces the same output using both of the formats...
 Output
Tue Feb 09 08:35:00 UTC 2016
Tue Feb 09 08:35:00 UTC 2016




Now lets see when the time zone is changed to +1030 i.e. 10 hours 30 minutes offset from GMT. Changing the time string to this...
 Time zone with a 30 minute component
...
String dtString = "20160209193500+1030";
...


...yields this output:
 Output
Tue Feb 09 09:05:00 UTC 2016
Tue Feb 09 09:35:00 UTC 2016


The Date object is now 30 minutes out if the lower precision time zone format is used.

Interestingly if the old 'Z' format is used i.e. 'yyyyMMddHHmmssZ', the time is parsed with the same precision in both cases.

So one would ask why should this new format be used when it has this precision issue/feature? Well the answer is that the ISO 8601 time zones are more versatile.

For example if you try to parse a 2-digit time zone (e.g. '20160209193500+11') using the old RFC 822 format, you will get this exception...
 Exception
Exception in thread "main" java.text.ParseException: Unparseable date: "20160209193500+11"
at java.text.DateFormat.parse(DateFormat.java:357)


-i

A quick disclaimer...

Although I put in a great effort into researching all the topics I cover, mistakes can happen. Use of any information from my blog posts should be at own risk and I do not hold any liability towards any information misuse or damages caused by following any of my posts.

All content and opinions expressed on this Blog are my own and do not represent the opinions of my employer (Oracle). Use of any information contained in this blog post/article is subject to this disclaimer.
Hi! You can search my blog here ⤵
NOTE: (2022) This Blog is no longer maintained and I will not be answering any emails or comments.

I am now focusing on Atari Gamer.