为什么“date”忽略 TZ 环境变量?

为什么“date”忽略 TZ 环境变量?

在 Ubuntu 18.04 上,我有以下行为date

$ date --version | head -n1
date (GNU coreutils) 8.28
$ date
Вт окт  8 13:18:18 MSK 2019
$ TZ=UTC date
Вт окт  8 10:18:23 UTC 2019

到目前为止,一切都很好。但现在我尝试在 Raspbian 9 上做同样的事情:

$ date --version | head -n1
date (GNU coreutils) 8.26
$ date
Tue Oct  8 13:18:50 MSK 2019
$ TZ=UTC date
Tue Oct  8 13:18:51 MSK 2019

dateRaspbian 版本忽略环境变量的原因可能是什么TZ

答案1

我可以想到两个可能的原因:

  1. 该文件/usr/share/zoneinfo/UTC在您的 Raspbian 9 上不存在或已损坏,因此glibc无法实现 TZ 变量设置并回退到系统默认时区,

  2. 您可能有一个先前配置的 TZ 变量已被标记为只读,因此您尝试更改它不会生效。

答案2

$TZ通过称为 UTC 且全年处于通用时间(与 0 偏移)的时区进行定义的正确、标准和可移植的方法是:

TZ=UTC0

这是独立的,并给出了该时区的完整规范。这表明与 UTC 的偏移量为 0(全年都是如此,因为没有指定 DST 部分)并且标签(例如报告的date +%Z)是 UTC。

所描述的时区规范TZ可能会变得更加复杂,因为您还可以嵌入 DST 名称和偏移量以及何时在夏令时和冬令时之间更改的规则。然而,这些规则是有限的,特别是不能涵盖规则从一年到另一年变化的情况(并且在大多数国家/地区,规则随着时间的推移而变化,或者使用与某个月的第一个或最后一个星期日不同的规则) 。

这就是为什么 POSIX 也指定TZ=:something了如何something处理左实现定义,以允许实现提出更好的方法来定义现实生活中的时区。

在大多数系统上,这是使用ICANN 的 tz 数据库(他们还发布了处理这些问题的参考代码)。

因此,您可以使用TZ=:Europe/London例如英国大陆时区,其中涵盖时区偏移以及伦敦当年和过去所有年份的变化时间。

在实践中,Europe/London被解释为文件相对于某个目录的路径zoneinfo(通常/usr/share/zoneinfo)。

在 tz 数据库中,还有一个Etc/UTC文件(包含该文件Etc/Universal及其Etc/Zulu链接)。Etc/GMT定义方式相同,但标签全年均为 GMT(使用Etc/GMT-0, Etc/GMT+0,Etc/Greenwich作为链接)。

因此,您可以TZ=:Etc/UTC得到与 UTC 相同的效果,TZ=UTC0只不过系统需要打开该Etc/UTC文件来找出最简单的 TZ 规则:全年与 UTC 的 0 偏移量。

在许多(大多数?)系统上,有一个UTC->Etc/UTC符号链接,因此您也可以执行TZ=:UTC.

TZ=UTC本身不是 POSIX,但在没有给出偏移量的情况下,在大多数系统上,它被解释为相同TZ=:UTC(在 中查找时区定义/path/to/zoneinfo/UTC。但如果 tz 数据库不可用,则不起作用。

另请注意,date特别是,您可以使用该-u选项来获取 UTC 日期,无论$TZ包含什么内容。date -u相当于TZ=UTC0 date.

相关内容