Date
級聯日期操作和優先級
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 舉了這些例子:jdebp % 日期 +%Y-%m-%d -d '2003-02-01 - 1 個月' 2003-01-01 jdebp % 日期 +%Y-%m-%d -d '2003-02-01 - 31 天' 2003-01-01 jdebp % 日期 +%Y-%m-%d -d '2003-02-01 - 31 天 + 1 個月' 2003-01-29 jdebp % 日期 +%Y-%m-%d -d '2003-02-01 - 1 個月 + 1 個月' 2003-02-01 jdebp % 日期 +%Y-%m-%d -d '2003-09-01 1 天前 + 1 個月' 2003-09-30 jdebp % 日期 +%Y-%m-%d -d '2003-09-01 1 天前' 2003-08-31 jdebp % 日期 +%Y-%m-%d -d '2003-08-31 + 1 個月' 2003-10-01 jdebp%
內部實際發生的情況
date
是,在計算過程中,它正在建構中間無效日期,在某些地方使用負值,2003-03-(-30)
例如。然後,在一切完成後,它使用 C 語言標準庫中的函式重新規範化這些無效日期。它沒有像人類那樣在每一步重新正規化。因此 2003-02-01 距 GNU 程序少 31 天
date
是一個無效日期,即負的 30th of February,而不是人類可能計算的一月份的有效日期。添加一個月,這將成為 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
一次性應用多個更改不會在每一步重新規範化。進一步閱讀
- 邁克爾·斯通 (2013-11-21)。
/bin/date
: 日期解析不一致。Debian 錯誤 #729952。- 烏爾夫·齊比斯 (2017-03-15)。 中適得其反的計算順序
date
。GNU 錯誤 #26101。- 文森特·勒費弗 (2018-02-06)。圍繞“wontfix”錯誤標籤的政策。debian 使用者。