Delphi - 获取非本地时区的 TTimeZone 并在时区之间转换 [重复]

Posted

技术标签:

【中文标题】Delphi - 获取非本地时区的 TTimeZone 并在时区之间转换 [重复]【英文标题】:Delphi - Get TTimeZone for non-local timezone and convert between timezones [duplicate] 【发布时间】:2013-02-28 05:43:22 【问题描述】:

我的主题可能措辞很糟糕,但这就是我所拥有的。

我有一个以本地时间报告时间戳的 Web 服务,如果服务器位于受影响的区域,则时间戳反映的是夏令时。 Web 服务还有第二个调用来检索 UTC 中的服务器时间,因此太平洋夏令时 (PDT) 中的服务器将其 UTC 偏移报告为 -08:00,即使它实际上是 -07:00,因为 PDT。

这是我调用返回服务器时区信息的结果。

太平洋标准时间;-480;(UTC-08:00) 太平洋时间(美国和加拿大);太平洋标准时间;太平洋夏令时间;[01:01:0001;12:31:2006;60;[0 ;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0 ;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];

因此,如果从 Web 服务返回的时间戳是 2013 年 3 月 12 日上午 12:00 并且 UTC 偏移量是 -08:00,并且我住在亚利桑那州的夏令时豁免区域,我的 UTC 偏移量是 -07: 00 如何将返回的时间戳转换为本地时间?

这里的杀手锏是在时间戳中使用本地时间的 Web 服务。如果他们坚持通用格式,我的生活会很轻松。我目前的想法是,如果我可以在 TTimeZone 或等效结构中获取服务器的信息,那么我可以使用 TTimeZone.IsDaylightTime(Timestamp) 函数来知道我是否需要在使用 -08:00 服务器之前从时间戳中减去一个小时偏移量和 -07:00 本地偏移量以获得正确的本地时间。

【问题讨论】:

【参考方案1】:

您可以使用delphi-tzdb。伪代码:

uses
  ..., TZDB;

procedure Main;
var
  ServerTZID: string;
  TZ: TTimeZone;
  Stamp1, Stamp2: TDateTime;
begin
  // 1. retrieve server timezone info
  ServerTZID := ... // MyServer.GetTimezoneInfo; e.g. 'Pacific Standard Time';
  // look up the retrieved timezone
  TZ := TBundledTimeZone.GetTimeZone(ServerTZID); // nil if not found
  // 2. retrieve server timestamp
  Stamp1 := ... // MyServer.RetrieveTimestamp;
  // 3. convert to UTC and back to local timezone
  Stamp2 := TZ.Local.ToLocalTime(TZ.ToUniversalTime(Stamp1));

  Writeln(Format('%s %s -> %s %s', [FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Stamp1),
    TZ.DisplayName, FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', Stamp2),
    TZ.Local.DisplayName]));
end;

【讨论】:

OP 显示的从服务器返回的时区 id 是 Microsoft Windows 时区,而不是 IANA/Olson TZDB 时区。 delphi-tzdb 做 CLDR 映射吗?如果没有,他将需要一个图书馆。我不知道有哪一款适合 Delphi。 CLDR映射数据为第二张表on this page @MattJohnson 它确实使用一些预定义的时区aliases(乍一看)看起来像 Windows 时区。 好的,看起来它们确实是从 CLDR 映射的。见this source。所以你的答案是正确的。这看起来是个不错的库。 谢谢,TOndrej。我今天会试一试。 @TOndrej,你就是那个男人。它就像一个魅力。我希望我昨天早上第一件事就发布了这个问题,而不是浪费几个小时来研究这个问题。谢谢!

以上是关于Delphi - 获取非本地时区的 TTimeZone 并在时区之间转换 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

使用本地时区在 Python 中获取正确的时区偏移量

如果有办法获取 bigquery 服务器的本地时区?

MySQL:获取特定时区的本地时间

在python中获取系统本地时区

如何在python烧瓶中获取具有本地时区的模板文件的修改日期

JS 根据时区获取时间