Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java DateFormat parse() doesn't respect the timezone

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));

try {
    System.out.println(df.format(cal.getTime()));
    System.out.println(df.parse(df.format(cal.getTime())));
} catch (ParseException e) {
    e.printStackTrace();
}

Here is the result:

2011-09-24 14:10:51 -0400

Sat Sep 24 20:10:51 CEST 2011

Why when I parse a date I get from format() it doesn't respect the timezone?

like image 605
Maxime Laval Avatar asked Sep 23 '11 18:09

Maxime Laval


People also ask

How do I set the timezone in Java?

You can make use of the following DateFormat. SimpleDateFormat myDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); myDate. setTimeZone(TimeZone. getTimeZone("UTC")); Date newDate = myDate.

What is UTC timezone in Java?

UTC stands for Co-ordinated Universal Time. It is time standard and is commonly used across the world. All timezones are computed comparatively with UTC as offset.

How do you show timezone in formatted date in Java?

You can display timezone easily in Java using SimpleDateFormat(“z”).


2 Answers

You're printing the result of calling Date.toString(), which always uses the default time zone. Basically, you shouldn't use Date.toString() for anything other than debugging.

Don't forget that a Date doesn't have a time zone - it represents an instant in time, measured as milliseconds since the Unix epoch (midnight on January 1st 1970 UTC).

If you format the date using your formatter again, that should come up with the same answer as before.

As an aside, I would recommend the use of Joda Time instead of Date/Calendar if you're doing any significant amount of date/time work in Java; it's a much nicer API.

like image 92
Jon Skeet Avatar answered Nov 15 '22 16:11

Jon Skeet


DateFormat.parse() is NOT a query (something that returns a value and doesn't change the state of the system). It is a command which has the side-effect of updating an internal Calendar object. After calling parse() you have to access the timezone either by accessing the DateFormat's Calendar or calling DateFormat.getTimeZone(). Unless you want to throw away the original timezone and use local time, do not use the returned Date value from parse(). Instead use the calendar object after parsing. And the same is true for the format method. If you are going to format a date, pass the calendar with the timezone info into the DateFormat object before calling format(). Here is how you can convert one format to another format preserving the original timezone:

    DateFormat originalDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy");
    DateFormat targetDateFormat = new SimpleDateFormat("EEE., MMM. dd, yyyy");

    originalDateFormat.parse(origDateString);
    targetDateFormat.setCalendar(originalDateFormat.getCalendar());
    return targetDateFormat.format(targetDateFormat.getCalendar().getTime());

It's messy but necessary since parse() doesn't return a value that preserves timezone and format() doesn't accept a value that defines a timezone (the Date class).

like image 26
Charlie Stear Avatar answered Nov 15 '22 15:11

Charlie Stear