简体   繁体   中英

Java timezone issue with Joda Time

I have a rather vexing issue with some date parsing and getting the right date/time from my formatting. Here's the code (condensed version) thats doing the formatting

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd");
log.debug("Trying to convert {} using format {}.", val, "yyyy-MM-dd");
Date toDate = formatter.parseDateTime(inputText).toDate();
log.debug("Converted value to {}", toDate);

Here's some output with the incorrect values. The timezone here is set to EDT. (checked via the date command and by the /etc/localtime symlink.

13:14:53.618 [http-bio-8080-exec-13] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Trying to convert 2013-07-08 using format yyyy-MM-dd.
13:14:53.619 [http-bio-8080-exec-13] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Converted value to Sun Jul 07 20:00:00 EDT 2013

This is running on AWS-LINUX on Tomcat 7 using OpenJDK 7. We have another instance running on AWS, and the same code produces this:

17:22:46.164 [http-bio-8080-exec-239] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Trying to convert 2013-07-08 using format yyyy-MM-dd.
17:22:46.165 [http-bio-8080-exec-239] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Converted value to Mon Jul 08 00:00:00 UTC 2013

The timezone on this machine is set to UTC.

On my local machine, the output is also correct (back to EDT here running oracles JDK on OS X):

13:24:55.967 [ajp-bio-8009-exec-176] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Trying to convert 2013-07-08 using format yyyy-MM-dd.
13:24:56.089 [ajp-bio-8009-exec-176] DEBUG c.s.e.p.j.AbstractParamToObjectProvider - Converted value to Mon Jul 08 00:00:00 EDT 2013

Again, same code in all three spots. I can not for the life of me figure out why we have an instance that does not act like the rest of them. I'm going to add some more debugging output to try and narrow it down, but as of right now I'm out of luck.

Also, another interesting bit. Running outside of Tomcat on the machine that is wrong, with the same jdk and the following code I get what I expect:

DateTimeFormatter f = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime parseDateTime = f.parseDateTime("2013-07-08");
System.out.println(parseDateTime.toDate());

Output:

Mon Jul 08 00:00:00 EDT 2013

UPDATE

It looks like Joda is not using the System default timezone. Here's how I'm outputting the data:

log.debug("Using joda timezone of: {}", DateTimeZone.getDefault());
log.debug("Default timezone of: {}", TimeZone.getDefault());

And here's the output:

AbstractParamToObjectProvider - Using joda timezone of: UTC
AbstractParamToObjectProvider - Default timezone of: sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]]

One of these things does not match the other...any ideas why?

SOLUTION

Jon was in the right direction with his answer, but here's the final run down.

Somehow user.timezone was set to UTC and Joda was using that, while the default TimeZone was not (that was using the system timezone). For a patch I did the following:

DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault()));

Just to make sure things match. A 'proper' fix is to set the system default timezone explicitly on app startup.

Joda Time goes through the following steps:

  • Use the user.timezone system property
  • Create a time zone based on the ID of TimeZone.getDefault()
  • Fall back to UTC

TimeZone.getDefault() can be a little bit more complicated, although it also uses user.timezone in many cases.

One option would be to explicitly set the default time zone for both TimeZone and DateTimeZone to UTC on application start-up: for web servers, it's the most reasonable default to use (although personally I prefer to explicitly state the time zone where appropriate).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM