Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to extract TimeZone object from a String?

Tags:

java

timezone

I have a database field that contains a raw date field (stored as character data), such as

Friday, September 26, 2008 8:30 PM Eastern Daylight Time

I can parse this as a Date easily, with SimpleDateFormat

DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");
Date scheduledDate = dbFormatter.parse(rawDate);

What I'd like to do is extract a TimeZone object from this string. The default TimeZone in the JVM that this application runs in is GMT, so I can't use .getTimezoneOffset() from the Date parsed above (because it will return the default TimeZone).

Besides tokenizing the raw string and finding the start position of the Timezone string (since I know the format will always be EEEE, MMMM dd, yyyy hh:mm aa zzzz) is there a way using the DateFormat/SimpleDateFormat/Date/Calendar API to extract a TimeZone object - which will have the same TimeZone as the String I've parsed apart with DateFormat.parse()?

One thing that bugs me about Date vs Calendar in the Java API is that Calendar is supposed to replace Date in all places... but then they decided, oh hey let's still use Date's in the DateFormat classes.

like image 827
matt b Avatar asked Sep 17 '08 17:09

matt b


2 Answers

I found that the following:

        DateFormat dbFormatter = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");
        dbFormatter.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
        Date scheduledDate = dbFormatter.parse("Friday, September 26, 2008 8:30 PM Eastern Daylight Time");
        System.out.println(scheduledDate);
        System.out.println(dbFormatter.format(scheduledDate));
        TimeZone tz = dbFormatter.getTimeZone();
        System.out.println(tz.getDisplayName());
        dbFormatter.setTimeZone(TimeZone.getTimeZone("America/Chicago"));
        System.out.println(dbFormatter.format(scheduledDate));

Produces the following:

Fri Sep 26 20:30:00 CDT 2008
Friday, September 26, 2008 08:30 PM Eastern Standard Time
Eastern Standard Time
Friday, September 26, 2008 08:30 PM Central Daylight Time

I actually found this to be somewhat surprising. But, I guess that shows that the answer to your question is to simply call getTimeZone on the formatter after you've parsed.

Edit: The above was run with Sun's JDK 1.6.

like image 180
Ed Thomas Avatar answered Sep 24 '22 22:09

Ed Thomas


@Ed Thomas:

I've tried something very similar to your example and I get very different results:

String testString = "Friday, September 26, 2008 8:30 PM Pacific Standard Time";
DateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy hh:mm aa zzzz");

System.out.println("The default TimeZone is: " + TimeZone.getDefault().getDisplayName());

System.out.println("DateFormat timezone before parse: " + df.getTimeZone().getDisplayName());

Date date = df.parse(testString);

System.out.println("Parsed [" + testString + "] to Date: " + date);

System.out.println("DateFormat timezone after parse: " + df.getTimeZone().getDisplayName());

Output:

The default TimeZone is: Eastern Standard Time

DateFormat timezone before parse: Eastern Standard Time

Parsed [Friday, September 26, 2008 8:30 PM Pacific Standard Time] to Date: Sat Sep 27 00:30:00 EDT 2008

DateFormat timezone after parse: Eastern Standard Time

Seems like DateFormat.getTimeZone() returns the same TimeZone before and after the parse()... even if I throw in an explicit setTimeZone() before calling parse().

Looking at the source for DateFormat and SimpleDateFormat, seems like getTimeZone() just returns the TimeZone of the underlying Calendar... which will default to the Calendar of the default Locale/TimeZone unless you specify a certain one to use.

like image 34
matt b Avatar answered Sep 25 '22 22:09

matt b