如何将 UTC 日期时间转换为指定的时区?

lok*_*oki 1 windows delphi winapi timezone datetime

看起来很简单,但我没有找到将 UTC 日期时间转换为指定时区的方法。我找到了如何将 UTC 日期时间转换为本地日期时间,但现在我想转换为特定时区(例如莫斯科时间)

例如在 c# 中,我们可以这样做:

// user-specified time zone
TimeZoneInfo southPole =
    TimeZoneInfo.FindSystemTimeZoneById("Antarctica/South Pole Standard Time");

// an UTC DateTime
DateTime utcTime = new DateTime(2007, 07, 12, 06, 32, 00, DateTimeKind.Utc);

// DateTime with offset
DateTimeOffset dateAndOffset =
    new DateTimeOffset(utcTime, southPole.GetUtcOffset(utcTime));

Console.WriteLine(dateAndOffset);
Run Code Online (Sandbox Code Playgroud)

但是在Delphi中怎么办呢?

Mat*_*int 8

一些东西:

  • "Antarctica/South Pole Standard Time"不是真正的时区标识符。我假设你是开玩笑的,但不清楚你是要使用 Windows 时区标识符(如"Eastern Standard Time")还是 IANA 时区标识符(如"America/New_York")。

  • 假设您想使用 Windows 标识符,您确实可以使用 Win32 API 中的函数。然而,问题中的评论暗示了错误的 API。您应该改为使用SystemTimeToTzSpecificLocalTimeEx.

    • 它使用DYNAMIC_TIME_ZONE_INFORMATION自 Windows Vista 以来一直可用的结构。要从命名的 Windows 时区标识符中获取其中之一,请使用该EnumDynamicTimeZoneInformation函数循环遍历系统时区,直到在该TimeZoneKeyName字段中找到匹配的时区。
    • “动态”结构使用起来很重要,并且应该始终优先于较旧的结构。它们允许访问存储在 Windows 注册表中的时区更改和夏令时规则。没有它们,您只能访问当前规则,这可能不是您要转换的日期的正确规则。
  • 如果你不是想用IANA时区标识符,使用德尔福TZDB库,如在这个岗位

    • 如果您不确定使用哪种方法,我强烈推荐这种方法。IANA 标识符可与其他操作系统、编程语言、框架和库互操作。(Windows 标识符,不那么重要。)