Java应用程序将事件写入日志文件,包括时间戳(从Date.toString()返回),后者又包含时区。在我使用的Windows机器上,我看到Date.toString()返回的字符串,其时区表示为三个字符的字符串(例如“CST”)。但是在某些客户机器上,日期被写入日志文件,时区表示为与GMT的偏移(例如“GMT-06:00”)。
我们有一个工具可以解析日志文件的文本以获取各种信息,但不幸的是,它的原始实现采用了三字符表示,并且不适用于那些具有GMT偏移表示的日志文件。我们已经修复了这个工具,现在对此无动于衷,但我们希望能够为运行旧版本的客户提供建议,并且由于他们的字符串具有GMT偏移时区而导致出现此问题,他们可以获得如果他们更改系统设置以便他们的日志文件使用三个字符的字符串时区字符串编写,则可以开始工作。此外,我们希望在未来的测试计划中考虑到这种可变性,确保我们使用每个设置进行测试。但是我无法确定Windows设置中的是什么告诉Java使用“CST”而不是使用“GMT-06:00”。
我看到了几个与时区相关的注册表设置,但我无法明确指出控制该特定选择。一些注册表设置引用tzres.dll。选择是否融入其中? 在Windows上有什么简单的方法可以让Date.toString()使用一个时区表示来表示其字符串而不是使用另一个时区吗?
答案 0 :(得分:0)
我不知道这种行为差异的确切原因,但我可以猜到。时区是UTC 和历史记录&的偏移量。有关该特定异常的信息,例如夏令时。某些计算机(或JVM默认值)可能只设置为偏移量而不是特定的命名时区。
java.util.Date类一般来说非常麻烦,应该避免使用。具体来说,toString
在两个方面很糟糕。 (A)正如您所发现的,它用于生成字符串的格式很糟糕。 (B)应用JVM的默认时区。该应用程序会导致混淆,因为它暗示Date具有时区,而实际上它没有。这种方法只能暂时用于快速和肮脏的目的,绝不能用于记录。
使用体面的日期时间库。这意味着Joda-Time或Java 8中的新java.time包。默认情况下,它们都使用合理且有用的ISO 8601格式。
通常最佳做法是以UTC时区进行记录(无偏移)。
示例:2014-05-04T10:36:34Z
在Joda-Time中生成这样的值:
String output = new DateTime( DateTimeZone.UTC ).toString();
如果您的问题是,"如何更改运行应用程序的JVM使用的时区我无法改变?",一种解决方案是通过传递一个JVM的时区来设置JVM的时区启动JVM时的参数。请参阅this question。