为什么 Unix 日期在 2 到 3 个月之间存在差异

Shi*_*ker 16 command-line-interface date

这怎么可能,我该如何处理?我正在制作依赖于 Unix 的备份脚本,date并发现了一个有趣的错误:

[root@web000c zfs_test]# date +%y-%m-%d --date='2 months ago'
14-04-01
[root@web000c zfs_test]# date +%y-%m-%d --date='3 months ago'
14-02-28
[root@web000c zfs_test]# date
Sun Jun  1 00:08:50 CEST 2014
Run Code Online (Sandbox Code Playgroud)

Mic*_*ton 44

由于夏令时(夏令时),您会看到这种行为。

因为您目前处于夏令时,您的时钟提前 1 小时,所以当您在三个月前的 6 月 1 日午夜刚过时询问,时间最终会“提前”一个小时,因为它不是夏令时 3几个月前。

GNU 日期文档建议通过使用中午 12:00 和每月 15 日作为起点来解决此问题,分别询问相对日期或月份。例如:

date +%y-%m-%d --date="$(date +%Y-%m-15) -3 month"
Run Code Online (Sandbox Code Playgroud)


And*_*w B 14

如果绝对时间是您的主要关注点,那么最好不要使用UTC,因为它存在于此目的。当您必须解决问题时,迈克尔的回答非常有用,但通常最好尽量避免。

当您的系统默认未设置为 UTC 时,传递时区的最简单方法是在您的命令前加上TZ环境变量。这将区域切换限制为单个命令,并防止变量泄漏到您的后续命令中。

$ NOW=$(date '+%s')
$ date -d @$NOW
Wed Jun 11 23:44:35 EDT 2014
$ TZ=UTC date -d @$NOW
Thu Jun 12 03:44:35 UTC 2014
Run Code Online (Sandbox Code Playgroud)

不应该做的是导出TZ变量,因为这会使故障排除变得非常混乱,如下所示。

$ export TZ=UTC
$ date -d @$NOW
Thu Jun 12 03:44:35 UTC 2014
$ TZ=EDT date -d @$NOW
Thu Jun 12 03:44:35 EDT 2014
Run Code Online (Sandbox Code Playgroud)