echo 20171231 | xargs -i date -d "{} +1 day" | xargs -i date -d "{} -1 month"
**Fri Dec 1 00:00:00 PST 2017**
在这种情况下,当日期格式命令通过管道传输时,我得到的是 12 月 1 日。
echo 20171231 | xargs -i date -d "{} +1day -1 month"
Sat Dec 2 00:00:00 PST 2017
而当日期格式包含在单个数据命令中时,结果为 12 月 2 日。
在上面的命令中,-1 月似乎优先于 +1 天。
有人可以帮助我了解这是如何工作的吗?
不,没有优先顺序。
具有讽刺意味的是,这个月刚出现在 Debian 用户的邮件列表中,有人指出,对于阅读假设的人类可读的自然语言日期操作命令的人来说,GNU
date
工具的行为似乎非常不一致。Vincent Lefèvre 举了这些例子:内部实际发生的事情
date
是,在计算过程中,它正在构造中间无效日期,其中某些地方有负值,2003-03-(-30)
例如。然后在一切都完成后,它使用 C 语言标准库中的函数重新规范化这些无效日期。它没有像人类那样在每一步重新归一化。因此 2003-02-01 减去 GNU 程序的 31 天
date
是无效日期,负的 2 月 30 日,而不是人类可能计算的 1 月的有效日期。添加一个月,这在 3 月成为无效日期,仍然是负 30,最终在 1 月重新规范化为该日期,因为当然调整为-30
大于零的数字会跳过整个 2 月。其他示例中未规范化的无效日期是2003-10-00
、2003-09-00
和2003-09-31
。将此应用于您的示例:
2017-12-31 + 1 day
是2017-12-32
,它在程序的输出中重新规范化为2018-01-01
。2018-01-01 - 1 month
是2018-00-01
,它在程序的输出中重新规范化为2017-12-01
。2017-12-31 + 1 day - 1 month
是2017-11-32
,它在程序的输出中重新规范化为2017-12-02
。正如您所看到的,当您在每一步重新规范化时,您不会得到与一次应用所有更改相同的结果,因为 GNU 一次
date
应用多个更改不会在每一步重新规范化。延伸阅读
/bin/date
: 日期解析不一致。Debian 漏洞 #729952。date
。GNU 错误 #26101。发生这种情况的原因是:
命令日期转到 12 月的月初。
当您添加 1 天时,它会转到 day
2
。相反,当这一天是 1 月 1 日时,它可以追溯到整整一个月
这是日期的内部特征。
date
返回上个月的相同日期编号:那是 11 月的给定日期可以追溯到 10 月。但如果那天是 31 号,它就会遇到麻烦。例如,从 10 月 31 日开始,没有 9 月 31 日,因此它可以追溯到 10 月 1 日:
只有当一天是 01 时,月班才准确,二月是一个特别奇数的月份:
因为没有 2 月 31 日。
在我看来,
date
首先要追溯到一个月,然后按此顺序添加日期。如果您更改管道中操作的顺序,您会得到与另一个相同的结果。
问题是从 12 月 31 日回溯一个月是有问题的。上个月的同一天是 11 月 31 日,但 11 月只有 30 天。从某种意义上说,11 月 31 日与 12 月 1 日相同,因此给出后者具有一定的逻辑性。
当然,另一种选择是从 12 月 31 日到 11 月 30 日,但这也不是完全没有问题。那么应该
Nov 30 - 1 month
是 10 月 30 日还是 10 月 31 日?您可能需要手动实现所需的逻辑。