我们有一个Web服务应用程序,它总是以UTC格式输入时间
2012-12-06T05:00:00.000Z
这是将日期解析为 java util Date 对象的代码
private static final Pattern PATTERN = Pattern.compile(
"(\d{4})(?:-(\d{2}))?(?:-(\d{2}))?(?:[Tt](?:(\d{2}))?(?::(\d{2}))?(?::(\d{2}))?(?:\.(\d{3}))?)?([Zz])?(?:([+-])(\d{2}):(\d{2}))?");
Matcher m = PATTERN.matcher(dateString);
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
int hoff = 0, moff = 0, doff = -1;
if (m.group(9) != null) {
doff = m.group(9).equals("-") ? 1 : -1;
hoff = doff * (m.group(10) != null ? Integer.parseInt(m.group(10)) : 0);
moff = doff * (m.group(11) != null ? Integer.parseInt(m.group(11)) : 0);
}
c.set(Calendar.YEAR, Integer.parseInt(m.group(1)));
c.set(Calendar.MONTH, m.group(2) != null ? Integer.parseInt(m.group(2))-1 : 0);
c.set(Calendar.DATE, m.group(3) != null ? Integer.parseInt(m.group(3)) : 1);
c.set(Calendar.HOUR_OF_DAY, m.group(4) != null ? Integer.parseInt(m.group(4)) + hoff: 0);
c.set(Calendar.MINUTE, m.group(5) != null ? Integer.parseInt(m.group(5)) + moff: 0);
c.set(Calendar.SECOND, m.group(6) != null ? Integer.parseInt(m.group(6)) : 0);
c.set(Calendar.MILLISECOND, m.group(7) != null ? Integer.parseInt(m.group(7)) : 0);
return c.getTime();
最近观察到一件奇怪的事情,当应用程序首次启动时,返回的日期将正确打印为2012年12月星期四 06 00:00:00 EST
因为我们处于美国东部标准时间。然后过了一段时间,经过一段时间的执行,即使没有重新启动应用程序,相同的日期也会打印为2012 年 12 月 6 日星期四 05:00:00 UTC
我一直在挖掘应用程序,我没有看到任何可以重置我们应用程序默认时区的更改。怎么会这样?自从我们开始研究这个问题以来已经一周了,我们仍然一无所知:-(
另外,是否有任何方法可以确保应用程序继续使用系统时区,因为这不会改变?
非常感谢任何帮助/提示
不幸的是,时区可以通过任何决定调用TimeZone.setDefault
的编写不佳的代码从应用程序下更改。 当第三方代码调用该方法时,我们实际上在我们的应用程序中被这个咬了。 不幸的是,解决方案是永远不要依赖应用程序开头之后的默认时区。 我们有一个核心类,它在启动时获取默认时区,所有需要使用系统默认值输出日期的后续代码都将显式使用这个隐藏实例(当然可以防止修改,不要忘记时区是可变的!