gpt4 book ai didi

java - Joda 时区与 JDK 的时区不同

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:34:43 24 4
gpt4 key购买 nike

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

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。

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

最佳答案

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

Gets the default TimeZone for this host. The source of the default TimeZone may vary with implementation.

所以简单的答案是 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(),它可能会或可能不会在其他线程中可见,具体取决于他们是否已经查找了该版本。如果您从调试调用中得到明显异常的结果,这很可能只是因为不同的线程可能有不同的默认时区

关于java - Joda 时区与 JDK 的时区不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4374733/

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