gpt4 book ai didi

Joda Time 的 Java 时区问题

转载 作者:行者123 更新时间:2023-11-28 22:06:38 24 4
gpt4 key购买 nike

我有一个相当棘手的问题,涉及一些日期解析和从我的格式中获取正确的日期/时间。这是进行格式化的代码(精简版)

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);

这是一些包含不正确 值的输出。这里的时区设置为美国东部时间。 (通过 date 命令和/etc/localtime 符号链接(symbolic link)检查。

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

这是在使用 OpenJDK 7 的 Tomcat 7 上的 AWS-LINUX 上运行的。我们有另一个在 AWS 上运行的实例,同样的代码产生了这个:

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

这台机器上的时区设置为 UTC。

在我的本地机器上,输出也是正确的(回到 EDT 此处在 OS X 上运行 oracles JDK):

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

同样,所有三个位置的代码相同。我一辈子都弄不明白为什么我们有一个实例不像其他实例那样行事。我将添加更多调试输出以尝试缩小范围,但截至目前我运气不好。

此外,还有一个有趣的地方。在错误的机器上在 Tomcat 之外运行,使用相同的 jdk 和以下代码,我得到了我期望的结果:

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

输出:

Mon Jul 08 00:00:00 EDT 2013

更新

看起来 Joda 没有使用系统默认时区。这是我输出数据的方式:

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

这是输出:

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]]

其中一个与另一个不匹配……知道为什么吗?

解决方案

Jon 的回答是正确的,但这是最后的总结。

不知何故 user.timezone 被设置为 UTC 而 Joda 正在使用它,而默认的 TimeZone 不是(使用系统时区)。对于补丁,我做了以下操作:

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

只是为了确保事情匹配。 “正确”的解决方法是在应用程序启动时明确设置系统默认时区。

最佳答案

Joda Time 经历了以下步骤:

  • 使用user.timezone 系统属性
  • 根据TimeZone.getDefault()的ID创建时区
  • 回到UTC

TimeZone.getDefault() 可能稍微复杂一些,尽管在许多情况下它也使用 user.timezone

一个选项是在应用程序启动时显式TimeZoneDateTimeZone 的默认时区设置为 UTC:对于 web服务器,这是最合理的默认使用(尽管我个人更喜欢在适当的地方明确说明时区)。

关于Joda Time 的 Java 时区问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18538504/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com