据我所知,美国东部时间是东部标准时间GMT-5,东部夏令时间GMT-4。
那么为什么这两个命令在答案中给出不同的时间呢?
laptop % TZ=EST5EDT date
Wed Apr 27 12:16:36 EDT 2022
laptop % TZ=GMT-4 date
Wed Apr 27 20:16:40 GMT 2022
Run Code Online (Sandbox Code Playgroud)
它们不应该是一样的吗?
tel*_*coM 10
实际上有两种使用 TZ 变量的主要方法。较旧的一个是在 POSIX 标准中指定的,它可以在实际变量中对时区和当年的夏令时规则进行编码。例如,欧洲 UTC+2 小时时区可能完全指定为以下 POSIX 风格:
TZ=EET-2EEST,M3.5.0/3,M10.5.0/4
Run Code Online (Sandbox Code Playgroud)
请注意,此格式假设当年的夏令时规则也适用于任何过去和未来的年份……这一假设不太可能正确。
由于这显然不太理想,因此许多 UNIX 风格的操作系统使用 TZ 环境变量作为对更扩展的时区信息表的引用,涵盖特定时区的当前和历史定义。
这些基于表格的实现中最全面的是 Olson 时区信息数据库,该数据库现在由 IANA 维护。Olson 风格的 TZ 值通常采用<Continent>/<City>
格式,但数据库也有一些其他选项。您可以在 TZ 变量中使用任一形式,但如果值不明确,则 POSIX 格式优先,因为它是既定的标准。
TZ 变量的 POSIX 标准定义与您自然假设的定义“相反”。第一个时区标签后面的数字标识必须添加到本地时间的小时数才能获取UTC 时间。
这可能是因为在 POSIX 标准制定之前,已经存在不同版本的 TZ 环境变量约定……并且由于 Unix 最初是在西半球开发的,因此现有约定倾向于使用正数表示美国时区。(在 Unix 的早期,可能没有人想到 MULTICS 操作系统开发项目的一个主要是学术性的分支会发展成为更大、更长久的东西。)
据我所知,POSIX 规范的开发人员尽最大努力找到已经最常见的行为,并将其编入标准,除非有非常明显的理由不这样做。
因此,TZ=GMT-4
以 POSIX 风格进行解释...然后它并不意味着“GMT 减去四个小时的时区”:它实际上意味着“比UTC 早四个小时且名为GMT 的时区”。我想,您可以将自定义时区命名为您想要的任何名称,但是将众所周知的历史时区标识符重复用于完全不同的内容会导致混乱。
如果您想在 Linux 中仅通过“GMT”指定时区,那么您应该通过添加前缀来使用较新的 Olson 风格的 TZ 设置Etc/
...即使这样,符号约定也与您期望的相反,可能是保持与旧的 POSIX 风格设置的类比。
比较:
$ TZ=Etc/GMT-4 date
Wed 27 Apr 21:09:32 +04 2022 # Olson: 4 hours east of UTC, timezone correctly identified numerically
$ TZ=GMT-4 date
Wed 27 Apr 21:09:50 GMT 2022 # POSIX: 4 hours east of UTC, misleading timezone identifier!
$ TZ=Etc/GMT+4 date
Wed 27 Apr 13:09:39 -04 2022 # Olson: 4 hours west of UTC, timezone correctly identified numerically
$ TZ=GMT+4 date
Wed 27 Apr 13:10:14 GMT 2022 # POSIX: 4 hours west of UTC, misleading timezone identifier!
$ date -u
Wed 27 Apr 17:10:25 UTC 2022 # UTC time for reference.
Run Code Online (Sandbox Code Playgroud)