【问题标题】:Posix timezone string to Olson stringPosix 时区字符串到 Olson 字符串
【发布时间】:2020-09-23 19:26:54
【问题描述】:

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

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

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

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

【问题讨论】:

  • but it only accepts Olson timezone descriptions 嗯,嗯,.. 不是timedatectl 接受这一点,而是时区数据库是这样构造的。我说,不可能将任何 posix 规范转换为 zoneinfo 条目 - 但您可以将所有 zoneinfo 条目转换为 posix 规范并拥有一个映射。但是,实际上,只需将TZ 设置为/etc/environment。如果不熟悉,请成为man tzfile localtime timedatectl。另一方面,您可以采用 posix 规范,生成一个 tzfile 并使用 timedatectl 进行设置。
  • 您也可以在DefaultEnvironment 中设置TZ/etc/systemd/system.conf - 假设systemd 是您的系统管理员,它会启动所有设置TZ 的服务,所以它会在任何地方设置.

标签: c linux timezone tdatetime


【解决方案1】:

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

但是,由于您说用户通过 Web 服务与系统进行交互,您可以改为考虑 投影 POSIX 字符串。用户将为设备选择一个 IANA 时区(或者您可以look it up by 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 issue #314 中有一些不受支持的代码可以利用或调整。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 2021-07-14
    • 1970-01-01
    • 2012-08-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-10
    相关资源
    最近更新 更多