4

我意识到这个问题可以通过编写一些测试代码来回答。我并不懒惰,我只是认为答案通常很有用。

我有一个应用程序生成了大量数据,其中记录了本地时间(由 NOW 例程返回)。我们遇到了夏令时进出转换的障碍 - 即当我们更改为 DST 时缺少一个小时,而当我们退出 DST 时又重复了一个小时。这会导致假定日期排序记录的操作出现问题。

因此,该应用程序已更改为使用 UTC 中的所有日期时间,但我将能够以 UTC 或本地时间显示日期时间。我还必须处理存储在本地时间的日期时间,并确保它们正确地转换为 UTC。这很棘手,因为日期时间可能在 DST 生效时已存储,因此在一般情况下,我需要能够确定任何随机日期是否在 DST 期间内或之外。当然有一个小时的时间段,日期时间是不明确的,可能在夏令时结束前的最后一小时,或者在夏令时结束后的第一个小时。没有办法解决这个问题。

在对更改进行编码时,我想知道 NOW 调用的结果。它在内部调用 GetLocalTime。当您处于 DST 期间时,GetLocalTime(和 NOW)会返回什么,但“调整时钟以更改夏令时”选项已关闭?

无论“调整时钟以进行夏令时更改”是关闭还是打开,如何编写一个例程来返回 DST 期间内的当前日期时间(应用 DST 偏差)?

4

2 回答 2

4

我认为你不能轻易解决你的问题。
变数太多了:

  • 存储的时间戳
  • 你所在的时区
  • 不断变化的时区规则
  • 确认这些时区规则在您使用的所有设备上都是准确的(即每个人总是应用他们的补丁)
  • 你的时钟不准确

有一个Delphi TZDB 项目可以帮助您了解时区规则。

我认为不依赖上述所有变量,而是存储三个字段更实用:

  • 本地格式的时间戳
  • 当前时区
  • UTC 格式的时间戳

您对第三个字段执行排序,前两个字段用于显示。

——杰伦

于 2011-01-12T10:57:27.530 回答
2

使用TzSpecificLocalTimeToSystemTime(及其明显的倒数)。这些允许您根据在本地日期/时间生效的夏令时设置在 UTC 和本地日期/时间之间进行转换。如果您希望您的应用程序在 XP 之前的任何设备上运行,请使用“延迟”函数属性加载此(从 kernel32):

function TzSpecificLocalTimeToSystemTime(lpTimeZoneInformation: PTimeZoneInformation;
  var lpLocalTime, lpUniversalTime: TSystemTime): BOOL; stdcall;

function TzSpecificLocalTimeToSystemTime; external kernel32 name 'TzSpecificLocalTimeToSystemTime' delayed;
于 2011-01-12T14:08:58.570 回答