1

我们有一个嵌入式 Linux 系统,用户需要能够通过提供 POSIX 字符串(例如 WEuropeStandardTime-1DaylightTime,M3.5.0,M10.5.0/3)来永久设置系统的时区。

用户通过我们开发的 Web 服务与系统交互,因此我们可以完全控制实现。我正在寻找 C/C++ 解决方案。

我一直在查看 timedatectl -set-timezone,但它只接受 Olson 时区描述,而不接受 POSIX 时区字符串。我在想我可以解析 tzdata 以找到 POSIZ 时区字符串的匹配项,但是在开始这条路径之前,我想知道是否有更好的方法,或者是否已经有一个库来进行这种转换。

我对设置 TZ 环境变量不以为然,因为它是对 timedatectl 设置的系统日期和时间的覆盖,感觉就像一个障碍。另外,我不确定如何尽早设置它以使所有从引导运行的软件都可以看到相同的时间。

4

1 回答 1

2

你问的是不可能的。在IANA(又名“Olson”)时区标识符后面表示的数据中包含的信息比 POSIX 时区字符串中的信息要多得多。特别是 POSIX 时区字符串只能包含一对转换规则。它没有提供任何工具来跟踪这些规则如何随着时间的推移而发生变化,或者它们在未来可能会如何变化。它也不提供标准时间偏移已更改或一年内有超过一对转换的情况。您可以在时区标签 wiki底部的“POSIX 风格时区”部分阅读更多相关信息。

但是,由于您说用户通过 Web 服务与系统交互,您可能会考虑投影一个 POSIX 字符串。用户将为设备选择一个 IANA 时区(或者您可以按 location 查找),然后您将其存储。然后在与设备通信时,您将生成一个 POSIX 字符串以在给定时间段内交付以在设备上使用。您可能希望定期更新它,也许每次设备签入或更新时(取决于您的场景)。

我知道一个内置此功能的商业产品:Azure Maps Timezone API。在其响应中,您会看到一个PosixTz字符串。(这是专门为物联网场景添加的。)

或者,您可以在自己的服务器端代码中自己执行此操作。逻辑有点棘手,但确实是可能的。

  • 如果你的后端是 .NET - 你很幸运。我的TimeZoneConverter.Posix库可以为您做到这一点。例如:

    string posix = PosixTimeZone.FromIanaTimeZoneName("Australia/Sydney");
    // Result: "AEST-10AEDT,M10.1.0,M4.1.0/3"
    
  • 如果您的后端是 JavaScript,那么Moment-Timezone 问题 #314中有一些不受支持的代码,您可以利用或调整这些代码。

  • 如果您的后端是其他东西,我不知道现成的解决方案。但是,您可以将上述任一代码中的代码移植到您的平台。

于 2020-09-23T21:29:04.570 回答