Delphi NOW 函数的结果如何受“调整时钟以进行夏令时更改”选项的影响

Posted

技术标签:

【中文标题】Delphi NOW 函数的结果如何受“调整时钟以进行夏令时更改”选项的影响【英文标题】:How is the result of the Delphi NOW function affected by the option to "Adjust clock for daylight saving changes" 【发布时间】:2011-06-07 12:01:04 【问题描述】:

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

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

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

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

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

【问题讨论】:

blogs.msdn.com/b/oldnewthing/archive/2003/10/24/55413.aspx 这里有一些不错的cmets。谢谢安德烈亚斯。 这里还有一些不错的 cmets:koders.com/delphi/… 【参考方案1】:

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

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

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

我觉得不依赖上述所有变量,而是存储三个字段会实用得多:

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

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

--杰罗恩

【讨论】:

+1 你说得对,整个区域都非常棘手;我喜欢你务实的解决方案【参考方案2】:

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

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

function TzSpecificLocalTimeToSystemTime; external kernel32 name 'TzSpecificLocalTimeToSystemTime' delayed;

【讨论】:

+1,但请注意,如果您的 Windows 在每次日期时间调用时都没有及时更新,则此函数会返回错误结果。 你能更详细地解释一下你的意思吗?您是指定期进行“Windows 更新”检查以捕获 TZ 定义更改吗?或者如果不是,那是什么?

以上是关于Delphi NOW 函数的结果如何受“调整时钟以进行夏令时更改”选项的影响的主要内容,如果未能解决你的问题,请参考以下文章

c#调用DELPHI的DLL出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏 请问在c#中怎么调用

delphi中如何计算当前日期与一个固定日期间的天数

Delphi 中的 FloatToStr(Now) 和 SQL Server 中的 Cast(GETDATE() as float) 之间的区别

Delphi高效定制格式的FormatDateTime

delphi真正实现延时暂停功能

Delphi:for循环期间函数结果未清空