How can I use Java's SimpleDateFormat to parse a timezone given as "GMT+0100 (BST)"?

13,149

Solution 1

"z" needs a colon between hours and minutes. "Z" is only +/-HHMM (i.e. no "GMT" prefix).

One way to parse it is: EEE MMM dd yyyy HH:mm:ss 'GMT'Z. The "BST" bit is ignored, and it's based on assumption that there's always "GMT" before offset.

Solution 2

I would parse out and interpret the time zone information separately, then use that to construct the Date/Calendar object in the proper time zone.

The following code seems to work well enough with your example:

String source = "Wed Aug 17 2011 09:57:09 GMT+0100 (BST)";
String tzid = "GMT" + source.substring(28, 31)
    + ":" + source.substring(31, 33);
TimeZone tz = TimeZone.getTimeZone(tzid);
// if (tz == null) ?
SimpleDateFormat f = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss");
f.setTimeZone(tz);
Date date = f.parse(source);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(date);

Prints "Wed Aug 17 08:57:09 UTC 2011".

A more sophisticated approach would be to use regex to extract individual parts ("+/-", "hh" and "mm") of the time zone offset.

Alternatively, you can attempt to discern the 3-letter time zone id (the string in between ( and )), and use the corresponding Java TimeZone if it exists.

In your particular example, though, "BST" resolves to Bangladesh Time which is GMT+0600 so you're better off with the numeric offset. "BST" here should probably be taken as British Summer Time (GMT+0100). This can be important because numeric offsets do not indicate the use of daylight savings time, which can be in effect depending on the date.

A more heuristic routine could take this into account and attempt to resolve the name first, but verify that the GMT offsets match, and fallback on the simple "GMT+hh:mm" timezones otherwise.

Share:
13,149
user898465
Author by

user898465

Updated on June 04, 2022

Comments

  • user898465
    user898465 almost 2 years

    I have a date that's in the form of:

    Wed Aug 17 2011 09:57:09 GMT+0100 (BST) 
    

    and have a filter that takes a time in a certain format. The problem seems to be the time zone on the end, none of the format strings I'm putting in the filter seem to work for this type of date format.

    For example,

    Wed Aug 17 2011 09:57:09 GMT+0100 (BST)
    EEE MMM dd yyyy HH:mm:ss zZ?
    

    The time zone part of this, keeps throwing an error.

    Can anyone tell me what the correct format to parse the time zones on these dates is?

  • user898465
    user898465 almost 13 years
    Konrad, thanks for the prompt answer, I tried it in the format EEE MMM dd yyyy HH:mm:ss 'GMT'Z and this still doesn't seem to be working. Could you elaborate on what you meant by 'z' needing a colon between the hours and minutes?
  • Konrad Garus
    Konrad Garus almost 13 years
    What do you mean by saying it doesn't work? new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z").parse("Wed Aug 17 2011 09:57:09 GMT+0100 (BST)") works just fine for me.
  • user898465
    user898465 almost 13 years
    I think the issues is that the program I am dealing with takes this date 'Wed Aug 17 2011 09:57:09 GMT+0100 (BST)' then asks for it to be converted into an object with the specified pattern. As it is technically a String being converted the '(BST)' parts needs to be counted for in the formatting. I found this format worked 'EEE MMM dd yyyy HH:mm:ss 'GMT'Z '(BST)''. This of course leaves me with the issue of the '(BST)' being hardcoded. Thanks
  • Konrad Garus
    Konrad Garus almost 13 years
    Do you really need (BST) in format string? It seemed to me that such extraneous thing was ignored.