Joda时区与JDK的时区不同 [英] Joda time zone different than JDK's

查看:108
本文介绍了Joda时区与JDK的时区不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的客户中,我有以下代码:

In my client, I have this code:

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

这两条线一个接一个地运行.我从不手动设置时区或user.timezone,而仅依靠从OS&本地系统.

These two lines run one after another. I never set time zone or user.timezone manually, just rely on defaults read from the OS & local system.

执行后,它们产生:

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

系统时区确实是Phoenix,而不是UTC. Joda如何正确而JDK错误呢?

System time zone is indeed Phoenix, not UTC. How can Joda be correct and JDK be wrong?

编辑:这是Windows 7 x64主机,JRE是1.6.22 x64.

EDIT: This is a Windows 7 x64 host, JRE is 1.6.22 x64.

编辑2 :请勿尝试复制它.它仅在部分系统上失败,而不是在所有系统上失败(例如我们的3k用户群中的几十个).我已经知道Joda先检查user.timezone,然后再检查TimeZone.getDefault().因此,我正在寻找一种解释,直接调用TimeZone和Joda自己进行调用之间有什么区别.

EDIT 2: Don't try to reproduce it. It only fails on some, not all systems (like a few dozen in our 3k user base). I already know Joda checks user.timezone and then TimeZone.getDefault(). So I am looking for an explanation on how can it be different between me calling TimeZone directly and Joda doing it by itself.

推荐答案

当您说从OS&本地系统读取默认值"时,没有一个明确定义的地方可以读取此默认值.甚至API文档本身都说

When you say "defaults read from the OS & local system", there isn't a single, well-defined place to read this default from. Even the API documentation itself says

获取此主机的默认TimeZone.默认TimeZone的来源可能会因实现方式而异.

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

因此,简单的答案是Joda和您的JVM从不同的信息源推断默认时区.需要记住的一点是,默认值是一个猜测,而不是JVM可以最终访问的内容.

So the simple answer is that Joda and your JVM are inferring the default time zone from different sources of information. The point to remember about this is that the default is a guess, not something that the JVM can definitively get access to.

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

For Sun's 1.5.0_06 JVM on Linux, the following order is used:

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

Joda 1.6.2使用:

Joda 1.6.2 uses:

  1. 系统属性user.timezone.
  2. 如果以上是null或不是有效的标识符,则使用JDK的TimeZone默认值.
  3. 如果失败,则使用UTC.
  1. The system property user.timezone.
  2. If the above is null or not a valid identifier, the value of the JDK's TimeZone default is used.
  3. If that fails, UTC is used.

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

So if you have the above versions of JDK and Joda, I suggest that the user.timezone property may be set in your environment. Other versions may will use other algorithms to acquire the default, though.

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

In Sun's JDK 1.6.0_22, the default search first inspects the user.timezone property as well, and if that isn't found it looks up the user.country property in order to get the default value for a country. If neither is set, the default of GMT is used. So the results you observe may well change with your JVM version.

如果您都拥有两个源(实际上两个源都可用),那么您可以简单地对其进行跟踪!逐步执行Joda调用,以查看它是否确实遵从java.util.TimeZone.getDefault(),并查看返回的值是什么.然后直接调用JDK方法,看看会得到什么.

Edit 2: If you've got the source to both (and indeed the sources are both available), then you can simply trace it! Step through the Joda call, to see if it does indeed defer to java.util.TimeZone.getDefault(), and see what the returned value is. Then invoke the JDK method directly and see what you get.

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

Looking at the JDK sources, it seems that the default timezone is accessed via an inheritable thread local. Thus if someone somewhere calls TimeZone.setDefault(), it may or may not be visible in other threads, depending on whether they've looked up the version already. If you're getting apparently anomalous results from debugging the calls, it could well be simply due to the fact that different threads can have different default TimeZones.

这篇关于Joda时区与JDK的时区不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆