带有时区的Java日期秘密改变了吗?

gig*_*gi2 2 java timezone date

我们有一个webservices应用程序,它总是以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();
Run Code Online (Sandbox Code Playgroud)

最近有一件奇怪的事情发现,当应用程序首次启动时,返回的日期将被正确打印为Thur Dec 06 00:00:00 EST 2012

因为我们在EST时区.然后经过一段时间,经过一些执行,即使没有重新启动应用程序,同一日期将打印为Thur Dec 06 05:00:00 UTC 2012

我一直在挖掘应用程序,我没有看到任何会重置我们的应用程序的默认时区的更改.怎么会发生这种情况?自从我们开始研究这个问题已经有一周了,我们仍然无能为力:-(

另外,无论如何都要确保应用程序继续使用系统时区,因为这不会改变?

非常感谢任何帮助/提示

jta*_*orn 5

不幸的是,TimeZone可以通过任何决定调用的编写错误的代码在应用程序下更改TimeZone.setDefault.当第三方代码调用该方法时,我们实际上被我们的应用程序咬了.遗憾的是,解决方案永远不会依赖于应用程序开始之后的默认TimeZone.我们有一个核心类,它在启动时获取默认的TimeZone,所有需要使用系统默认输出日期的后续代码将明确使用这个存储的实例(当然这是防止修改,不要忘记TimeZone是可变的! ).