如果第一个参数不是 1,则 date 会错误地处理它

如果第一个参数不是 1,则 date 会错误地处理它

我正在使用date (GNU coreutils) 8.22并在计算给定日期之后的日期时遇到一些麻烦。

假设我想使用 2 月 1 日,例如:

$ date -d'1 February'
Sun Feb  1 00:00:00 CET 2015

然后我想在日期上添加一周。到目前为止,一切都很好:

$ date -d '1 February + 1 week'
Thu Feb  8 00:00:00 LMT 0001

但如果我添加一些东西作为第一项不是 1,它会失败并返回不正确的内容:

$ date -d '1 February + 2 weeks'  # returns as if it was +1 week
Fri Feb  8 00:00:00 LMT 0002      # but Fri instead of Thu, also LMT 0002

但是,如果我们在前面添加更多参数,它就会起作用:

$ date -d '1 February + 0 minutes + 2 week' # works since we added 0/1 unit before
Tue Feb 15 00:01:00 LMT 0000
$ date -d '1 February + 1 minute + 1 day + 1 week' # works fine
Fri Feb  9 00:01:00 LMT 0001
$ date -d '1 February + 1 minute + 25 day + 7 week'  # works since 1st parameter is 1!
Mon Apr 16 00:01:00 LMT 0001

请注意,如果我们提供相对日期,则不会发生这种情况:

$ date -d 'today + 1 week'
Wed Jul  1 12:20:03 CEST 2015
$ date -d 'today + 2 week'    # works fine
Wed Jul  8 12:20:12 CEST 2015

那么,为什么要date考虑第一个参数始终为 1,并且如果日期是用特定日期给出的,则会执行一些奇怪的操作?

答案1

好吧,我做了一些研究,它将第一个数字解释为年份,看起来+完全肤浅且完全被忽略。

使用你的例子。

$ date -d'1 February'
Sun Feb  1 00:00:00 CET 2015

完全按预期工作,因为没有提供年份。

$ date -d '1 February + 1 week'
Thu Feb  8 00:00:00 LMT 0001

看起来几乎是正确的,但您会注意到年份已更改为,0001因为+被忽略,因此该命令被视为

 {1 February 1} {+ 1}{week}
      date      

在该日期之后的任何时间段内,{+1} 似乎都是默认值。


您的另一个示例似乎有效但无效

$ date -d '1 February + 1 minute + 25 day + 7 week'  # works since 1st parameter is 1!
Mon Apr 16 00:01:00 LMT 0001

正如您所看到的,年份已增加到 0001。分钟已被引用,因此按默认值 1 递增,然后所有其他命令都不是日期的一部分,因此会相应地递增。


作为这种方式工作的进一步证明,请看这个确实有效的例子

$date -d '1 February 4 5 weeks'
Sun Mar  7 00:00:00 LMT 0004

和工作原理一样

$date -d '1 February + 4 + 5 weeks'
Sun Mar  7 00:00:00 LMT 0004

这意味着 + 会被忽略,如果之前未指定年份,则它们后面的第一个数字将被视为年份。

显然,如果您想减去,则必须明确说明,但如果没有为第一个数字指定年份,则仍然会被忽略。

$date -d '1 February -4 weeks'
Sun Feb  8 00:00:00 LMT 0004
                         ^
                         Year incremented by 4.

尽管如果您以手册页中指定的格式使用它,即

$date -d ' Feb 2 -4 weeks'
Mon Jan  5 00:00:00 GMT 2015

然后它将完全按预期工作,无需任何年份:)

答案2

它似乎将第二位数字解释为年份,然后假设 1 周,所以总是添加一年,因为this year这样我认为你会得到你想要的。例如。

christian@fujiu1404:~$ date -u -d'1 feb this year -2 weeks'
Sun Jan 18 00:00:00 UTC 2015
christian@fujiu1404:~$ date -u -d'1 feb this year +2 weeks'
Sun Feb 15 00:00:00 UTC 2015
christian@fujiu1404:~$ date -u -d'1 feb this year +3 weeks'
Sun Feb 22 00:00:00 UTC 2015

相关内容