Joda时区与JDK的时区不同 [英] Joda time zone different than JDK's
问题描述
在我的客户中,我有以下代码:
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 defaultTimeZone
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:
- 查看环境变量TZ
- 查找文件/etc/sysconfig/clock并尝试找到"ZONE"条目.
- 以递归方式将/etc/localtime的内容与/usr/share/zoneinfo中每个文件的内容进行比较.当内容匹配时,它将返回从/usr/share/zoneinfo引用的路径和文件名.
Joda 1.6.2使用:
Joda 1.6.2 uses:
- 系统属性
user.timezone
. - 如果以上是
null
或不是有效的标识符,则使用JDK的TimeZone
默认值. - 如果失败,则使用
UTC
.
- The system property
user.timezone
. - If the above is
null
or not a valid identifier, the value of the JDK'sTimeZone
default is used. - 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屋!