在 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
date
Raspbian 版本忽略TZ
环境变量的原因可能是什么?
我可以想到两个可能的原因:
该文件
/usr/share/zoneinfo/UTC
在您的 Raspbian 9 上不存在或已损坏,因此glibc
无法实现 TZ 变量设置并回退到系统默认时区,您可能有一个先前配置的 TZ 变量已标记为只读,因此您尝试更改它不会生效。
$TZ
通过称为 UTC 并且全年处于世界时(偏移量为 0)的时区定义的正确、标准和可移植的方法是:这是独立的,并给出了该时区的完整规范。这表明与 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 规则之外,您可以执行
TZ=:Etc/UTC
相同的操作:0 偏移到 UTC 全年。TZ=UTC0
Etc/UTC
在许多(大多数?)系统上,有一个
UTC
->Etc/UTC
符号链接,所以你也可以使用TZ=:UTC
.TZ=UTC
它本身不是 POSIX,但在没有给出偏移量的情况下,在大多数系统上,它被解释为与TZ=:UTC
(在 中查找时区定义/path/to/zoneinfo/UTC
。但如果 tz 数据库不可用,那将不起作用。另请注意,
date
特别是,您可以使用该-u
选项来获取 UTC 日期,而不管$TZ
包含什么。date -u
相当于TZ=UTC0 date
。