我已经实现了一个服务器端应用程序,它可以在创建和更新记录时记录时间戳。该应用程序假设服务器时钟没有启用夏令时,(a)因为我读过这是最佳做法和(b)因为我认为处理发生的歧义会很棘手(如果不是不可能的话),例如当时钟在十月份回归一个小时。
为安全起见,如果应用程序在启动时检测到DST已启用,则会记录错误并终止应用程序。即使应用服务器时钟已启用DST,我也会被内部利益相关者请求使应用程序正常工作。
我觉得尝试这样做是个愚蠢的事情,但我需要说服管理层。只是因为它使实现变得更加棘手,或者它是否存在根本上的缺陷,以至于这样的应用程序(记录时间戳)在一年中的任何时候都无法正确运行100%?在没有启用DST的情况下运行这样的应用程序的最佳理由是什么?
我想出的最好的是:
启用夏令时时,每年有两次不连续。请考虑以下情形,其中服务器在英国运行,时钟设置为启用夏令时的本地时间:2009年10月25日凌晨2点,时钟回到1点钟到凌晨1点。 记录于凌晨1点30分创建 应用程序(必须以UTC格式存储时间戳)无法判断这是在时钟返回之前或之后的1.30am,因此无法确定是否在调整中包含额外的小时到UTC。
这是真的吗?实际上是否可以确定(在Java Web应用程序中)10月25日凌晨1点30分发生的事件是在时钟调整之前还是之后?
避免夏令时的任何更好的理由?
更新
为了清楚起见,应用程序必须存储次为UTC。问题是为什么在尝试这样做时,在服务器计算机上启用DST是个坏主意。
答案 0 :(得分:14)
我发现(从多年的不良经历中)最好将日期和时间存储为UTC,并且只在用户想要查看时将它们转换为当地时间。
此外,让用户输入本地时间,但在存储之前将其转换为UTC。
这将为您节省各种问题,包括尝试弄清楚当您的应用程序分布在多个时区时会发生什么。
如果您只获得并存储UTC时间,则DST无关紧要。
我们继承的一个特别讨厌的应用程序发送了带有跨时区的时区的本地时间消息,需要花费大量精力来经常修改这些消息。
当我们将其修改为仅使用UTC时,它会好得多。一端尽可能早地转换为UTC,转换到当地时间推迟到最后一刻。代码变得更小,速度更快。
答案 1 :(得分:5)
没有理由在服务器上禁止DST,因为时区(或者我应该说“应该”)只是格式化。系统时钟与时区无关。时间戳应该以明确的格式存储,可以是“自上一个时刻开始”,如System.currentTimeMillis()
及其同类(与时区无关),也可以是指定了UTC偏移的文本(然后变为明确,如{{ 3}})。
答案 2 :(得分:0)
只要您使用内置Java类来存储日期和时间,DST就不应该成为问题。时间的内部表示是“1970年1月1日午夜,格林威治英格兰”的毫秒,所以你所在的时区或者夏令时是否生效是无关紧要的。
永远不要尝试使用文本表示比较两个日期或时间,例如“10/09/2009”或其他。使用长毫秒值。我正在研究一个系统,原来作者每次想要比较两个日期时都会使用不同的方法。在一个地方,他们将日期表示为yyyy / mm / dd,然后去除斜线,将结果转换为整数 - 因此10/08/2009变为20,091,008 - 然后将它们相互比较。其他时候他们将它们比作文本字符串。等等。当涉及多个时区或DST时,这会在整个地方给出不正确的结果。