【问题标题】:Convert datetime from one timezone to another (native C++)将日期时间从一个时区转换为另一个时区(本机 C++)
【发布时间】:2011-03-11 23:26:28
【问题描述】:

来自世界各地的客户可以向我的服务器应用程序发送某些“请求”。所有这些客户都位于许多不同的时区。

对于每个请求,我都需要将请求映射到内部 C++ 类实例。每个类实例都有一些关于其“位置”的信息,这些信息也由时区指示。

每个客户都可以发送与属于不同时区的实例相关的请求。为了防止我的客户将所有内容自己转换为“目标”实例的时区,我必须自己将所有内容从一个时区转换为另一个时区。但是,我只能在 C++(非托管、本机)函数中找到在本地时间和 GTM 之间转换时间的函数,而不是从/到不是您当前时区的时区。

我可以要求我的客户以 UTC 或 GTM 格式发送每个日期时间,但这并不能解决我的问题,因为我仍然需要将其转换为“实例”的时区,该时区可以是世界。

我似乎也没有找到执行此操作的 Windows 功能。我确实找到了一个可以执行此操作的托管 .Net 类,但我想让我的应用程序严格不受管理。

是否有任何我可以使用的 Windows(XP、Vista、7、2003、2008)功能(我在文档中忽略了这些功能),或者是否有任何其他免费算法可以在一个时区和另一个时区之间进行转换?

请注意,造成问题的不是 GMT 时差,而是似乎取决于时区的实际 DST 转换时刻。例如:

  • 西欧在 4 月 1 日之前的最后一个星期日从非 DST 变为 DST。
  • 美国在 3 月 1 日之后的第二个星期日从非 DST 进入 DST。
  • 中国没有夏令时。
  • 澳大利亚在 10 月 1 日之后的第一个星期日从非 DST 进入 DST。

所有这些 DST 转换信息都可以在 Windows 注册表的某个位置找到。问题是:我可以使用哪个 Windows 函数来利用这些信息。

【问题讨论】:

  • 夏令时过渡是当地的政治决定。不惜一切代价避免这种情况,让客户端机器进行本地到/从 UTC 转换。
  • @Hans,问题在于服务器正在管理分布在世界各地的仓库,每个仓库都有自己的开/关时间。要求客户将他们的本地时间转换为 UTC 很容易,但我还需要将所有仓库的开/关时间转换为 UTC,为此,我需要他们的时区信息。
  • 好吧,不要问你的客户。让它自动化。
  • @Hans:举个例子——作为一个澳大利亚人,我可以告诉你,上面的第四个点实际上是错误的——不是每个澳大利亚州都使用 DST,也不是所有其他州都使用 DST它在同一天。它甚至比每个国家/地区的规则复杂。
  • @Mac:是的,在美国也一样。亚利桑那州、印第安纳州和部落地区的县。

标签: c++ windows timezone


【解决方案1】:

我不知道通过 API 提取有关其他 TimeZone 的信息的方法:我已经看到它通过查询注册表来完成(我们在基于 WindowsCE 的产品中执行此操作)。

TimeZone 被定义为

下的注册表项
HKLM\Software\Microsoft\Windows NT\Current Version\Time Zones

每个键都包含多个值,告诉您偏移量和夏令时的值是 TZI 键。这是一个二进制 blob,它表示这种结构:

typedef struct
{
    LONG m_nBias;
    LONG m_nStandardBias;
    LONG m_nDaylightBias;
    SYSTEMTIME m_stcStandardDate;
    SYSTEMTIME m_stcDaylightDate;
} TZI;

查看 MSDN 的 TIME_ZONE_INFORMATION 页面 (http://msdn.microsoft.com/en-us/library/ms725481(v=VS.85).aspx),了解如何解释 Bias 字段,尤其是 StandardDate 和 DaylightDate 字段——它们被轻轻滥用以支持诸如“四月的最后一个星期六”之类的构造。

HTH

【讨论】:

  • 谢谢,通过您的链接,我找到了 Windows 函数 GetTimeZoneInformationForYear (>= Vista SP1),它返回特定时区的此信息。问题是:我没有找到这个函数的示例代码,并且函数文档没有明确说明应该将哪些输入数据准确地提供给这个函数。你有例子吗?
  • @Patrick - 恐怕我没有一个例子:因为我们正在开发 WinCE,所以我们没有 GetTimeZoneInformationForYear() 作为选项。但我不确定它是否对您有很大帮助:如果我理解正确,您想获得远程客户的时区,而不是任意年份的计算机时区。
猜你喜欢
  • 1970-01-01
  • 2015-02-21
  • 2019-06-19
  • 1970-01-01
  • 2015-11-05
  • 2021-01-23
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多