【问题标题】:Joda time zone different than JDK'sJoda 时区与 JDK 不同
【发布时间】:2010-12-07 17:01:09
【问题描述】:

在我的客户中,我有这个代码:

System.out.println("Java tz: " + TimeZone.getDefault());
System.out.println("Joda tz: " + ISOChronology.getInstance());

这两行一个接一个。我从不手动设置时区或user.timezone,只依赖从操作系统和本地系统读取的默认值。

执行时,它们会产生:

Java tz: sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Joda tz: ISOChronology[America/Phoenix]

系统时区确实是凤凰城,而不是 UTC。 Joda怎么会是对的而JDK是错的呢?

编辑:这是一个 Windows 7 x64 主机,JRE 是 1.6.22 x64。

EDIT 2:不要试图复制它。它只在某些系统上失败,而不是在所有系统上(比如我们 3k 用户群中的几十个)。我已经知道 Joda 检查user.timezone,然后检查TimeZone.getDefault()。所以我正在寻找一个解释,说明我直接打电话给TimeZone 和 Joda 自己打电话有什么不同。

【问题讨论】:

  • 我已经在我的 Windows 机器上使用 JDK 1.6.0_22 对其进行了测试,它显示的是我的时区,而不是 UTC。也许你应该添加更多信息:操作系统、JDK 版本,也许是一些环境变量?

标签: java jodatime


【解决方案1】:

当您说“从操作系统和本地系统读取默认值”时,没有一个明确定义的位置可以从中读取此默认值。甚至 API 文档本身都说

获取此主机的默认 TimeZone。默认TimeZone 的来源可能因实现而异。

所以简单的答案是 Joda 和您的 JVM 从不同的信息来源推断默认时区。关于这一点要记住的一点是,默认值是猜测,不是 JVM 可以明确访问的。

对于 Linux 上 Sun 的 1.5.0_06 JVM,使用以下顺序:

  1. 查看环境变量 TZ
  2. 查找文件 /etc/sysconfig/clock 并尝试查找“ZONE”条目。
  3. 递归比较 /etc/localtime 的内容与 /usr/share/zoneinfo 中每个文件的内容。当内容匹配时,它返回路径和文件名,引用自 /usr/share/zoneinfo。

Joda 1.6.2 使用:

  1. 系统属性user.timezone
  2. 如果上面是null 或不是有效标识符,则使用JDK 的TimeZone 默认值。
  3. 如果失败,则使用UTC

所以如果你有以上版本的JDK和Joda,我建议可以在你的环境中设置user.timezone属性。不过,其他版本可能会使用其他算法来获取默认值。

编辑:在 Sun 的 JDK 1.6.0_22 中,默认搜索首先也会检查 user.timezone 属性,如果没有找到,它会查找 user.country 属性以获得一个国家/地区的默认值.如果两者均未设置,则使用默认值GMT。因此,您观察到的结果可能会随着您的 JVM 版本而改变。


编辑 2:如果您有两者的来源(并且确实来源都可用),那么您可以简单地追踪它!单步执行 Joda 调用,查看它是否确实遵循 java.util.TimeZone.getDefault(),并查看返回值是什么。然后直接调用JDK方法,看看得到了什么。

查看 JDK 源代码,似乎默认时区是通过可继承的本地线程访问的。因此,如果有人在某处调用TimeZone.setDefault(),它可能会或可能不会在其他线程中可见,具体取决于他们是否已经查找过版本。如果您在调试调用时得到明显异常的结果,这很可能是因为不同的线程可以有不同的默认时区

【讨论】:

  • 谢谢,但它仍然没有回答我的问题。我已经知道 JDK 和 Joda 都使用相同的机制(user.timezone,然后是TimeZone.getDefault())。这就是我要问的原因:一个与另一个不同怎么可能?
  • @Konrad - 已更新,尝试在调试器中检查行为,看看这是否是 ThreadLocal 问题。
  • 我想补充一点,我更喜欢使用包含 -Duser.timezone=Europe/Warsaw 在内的命令行从 .bat 或 shell 脚本启动我的 Java 程序(当然,将其更改为您的时区)。
  • 感谢您的详细回答,但最终似乎原因更可能是:joda-time.sourceforge.net/tz_update.html。 @Michał:这就是我要使用的,但它需要更多的工作,因为我有更多时区的用户。谢谢你们。
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 2011-11-18
  • 2013-07-02
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多