hymie Asked: 2022-04-28 08:18:17 +0800 CST2022-04-28 08:18:17 +0800 CST 2022-04-28 08:18:17 +0800 CST 我的 zoneinfo 是倒退还是我很困惑 772 据我所知,美国东部时间是东部标准时间的 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 他们不应该是一样的吗? date timezone 1 个回答 Voted Best Answer telcoM 2022-04-28T09:55:01+08:002022-04-28T09:55:01+08:00 实际上有两种主要的方式来使用 TZ 变量。较旧的在 POSIX 标准中指定,它可以在实际变量中编码时区和当年的夏令时规则。例如,欧洲 UTC+2 小时时区可能完全指定为以下 POSIX 样式: TZ=EET-2EEST,M3.5.0/3,M10.5.0/4 EET =“标准时间”时区 ID(“东欧时间”) -2 = 您必须添加到本地时间才能获得 UTC 的偏移量 EEST = DST 时区 ID(“东欧夏令时间”) M3.5.0/3 = DST 于当地时间 3 月最后一个星期日 03:00:00 生效 M10.5.0/4 = 标准时间恢复 10 月最后一个星期日,当地时间 04:00:00 请注意,此格式假定当前年份的 DST 规则也适用于任何过去和未来的年份……这种假设不太可能是正确的。 由于这显然不太理想,许多 unix 风格的操作系统使用 TZ 环境变量作为对更扩展时区信息表的引用,涵盖特定时区的当前和历史定义。 这些基于表的实现中最全面的是 Olson 时区信息数据库,现在由 IANA 维护。Olson 风格的 TZ 值通常采用<Continent>/<City>格式,但数据库也有一些其他选项。您可以在 TZ 变量中使用任何一种形式,但如果值不明确,则 POSIX 格式优先,因为它是已建立的标准。 TZ 变量的 POSIX 标准定义是您可能自然假设的“倒退”。第一个时区标签后面的数字标识您必须添加到本地时间才能获得UTC 时间的小时数。 这可能是因为在开发 POSIX 标准之前,已经存在不同版本的 TZ 环境变量约定......并且由于 Unix 最初是在西半球开发的,现有的约定倾向于使用美国时区的正数。(在 Unix 的早期,没有人可能猜到 MULTICS OS 开发项目的主要学术分支会成长为更大、更长寿的东西。) 我了解到,POSIX 规范的开发人员尽其所能找到已经最常见的行为,并将其编入标准,除非有非常明显的理由不这样做。 因此,TZ=GMT-4以 POSIX 风格进行解释......然后它并不意味着“格林威治标准时间减去四个小时的时区”:它实际上意味着“比 UTC 提前四个小时并命名为GMT 的时区”。我猜你可以随意调用你的自定义时区,但是将一个众所周知的历史时区标识符重新用于完全不同的东西会引起混乱。 如果您想在 Linux 中仅通过“GMT”来指定时区,那么您应该通过添加Etc/前缀来使用更新的 Olson 风格的 TZ 设置……即使这样,符号约定也与您所期望的相反,可能是保持与旧 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.
实际上有两种主要的方式来使用 TZ 变量。较旧的在 POSIX 标准中指定,它可以在实际变量中编码时区和当年的夏令时规则。例如,欧洲 UTC+2 小时时区可能完全指定为以下 POSIX 样式:
请注意,此格式假定当前年份的 DST 规则也适用于任何过去和未来的年份……这种假设不太可能是正确的。
由于这显然不太理想,许多 unix 风格的操作系统使用 TZ 环境变量作为对更扩展时区信息表的引用,涵盖特定时区的当前和历史定义。
这些基于表的实现中最全面的是 Olson 时区信息数据库,现在由 IANA 维护。Olson 风格的 TZ 值通常采用
<Continent>/<City>
格式,但数据库也有一些其他选项。您可以在 TZ 变量中使用任何一种形式,但如果值不明确,则 POSIX 格式优先,因为它是已建立的标准。TZ 变量的 POSIX 标准定义是您可能自然假设的“倒退”。第一个时区标签后面的数字标识您必须添加到本地时间才能获得UTC 时间的小时数。
这可能是因为在开发 POSIX 标准之前,已经存在不同版本的 TZ 环境变量约定......并且由于 Unix 最初是在西半球开发的,现有的约定倾向于使用美国时区的正数。(在 Unix 的早期,没有人可能猜到 MULTICS OS 开发项目的主要学术分支会成长为更大、更长寿的东西。)
我了解到,POSIX 规范的开发人员尽其所能找到已经最常见的行为,并将其编入标准,除非有非常明显的理由不这样做。
因此,
TZ=GMT-4
以 POSIX 风格进行解释......然后它并不意味着“格林威治标准时间减去四个小时的时区”:它实际上意味着“比 UTC 提前四个小时并命名为GMT 的时区”。我猜你可以随意调用你的自定义时区,但是将一个众所周知的历史时区标识符重新用于完全不同的东西会引起混乱。如果您想在 Linux 中仅通过“GMT”来指定时区,那么您应该通过添加
Etc/
前缀来使用更新的 Olson 风格的 TZ 设置……即使这样,符号约定也与您所期望的相反,可能是保持与旧 POSIX 样式设置的类比。相比: