这怎么可能?我该如何处理?我正在编写依赖于 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
答案1
您看到这种行为是因为夏令时。
因为您目前处于夏令时,您的时钟快了一个小时,所以当您在六月一日午夜刚过后询问三个月前的时间时,时间最终会“早”一个小时,因为三个月前不是夏令时。
GNU 日期文档建议解决这个问题分别使用中午 12:00 和每月 15 日作为起始点,以查询相对日或相对月。例如:
date +%y-%m-%d --date="$(date +%Y-%m-15) -3 month"
答案2
如果你最关心的是绝对时间,那么最好世界标准时间因为它就是为此目的而存在的。Michael 的答案对于您必须在问题内部工作时非常有用,但通常最好尽可能完全避免它。
如果您的系统默认未设置为 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
你不应该要做的是导出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
答案3
在您的计算机认为它正在运行的这个特定年份,以及您为测试选择的特定日期“1 个月前、2 个月前和 3 个月前,是的 - 它很可能是 2 月 29 日的检测。并不总是错误,但是......
现在,今天不是 2014-06-01。再试一次。将计算机日期设置为 2013-06-01。再试一次。
将计算机日期设置为 2014-09-01。再试一次。