我需要计算两个日期之间的天数差异。使用 date 命令,我们可以将日期转换为秒,然后计算天数差异。\n例如:
\n$ echo $((($(date +%s --date "2023-10-21")-$(date +%s --date "1899-12-29"))/(3600*24)))\n 45220\nRun Code Online (Sandbox Code Playgroud)\n当第一次约会是积极的时候,一切都很好。当第一个日期为负数时,它不起作用。例如:
\n$ echo $((($( date +%s --date "-2022-05-10")-$(date +%s --date "1899-12-29"))/(3600*24)))\ndate: invalid date \'-2022-05-10\'\n25570\nRun Code Online (Sandbox Code Playgroud)\n另一方面,DATE 命令可以使用负日期进行操作:
\n$ date --date="3000 years ago"\nMon Nov 24 13:12:27 LMT -977\nRun Code Online (Sandbox Code Playgroud)\n别的。据我所知,消极日期和积极日期有一些差异。
\n对于正日期,一年从 1 月 1 日开始。但对于负日期,一年从 12 月 31 日开始:
第一年:...-29.12.01 -30.12.01 -31.12.01 [0000] +01.01.01 +02.01.01 +03.00.01... :第一年 +
\n关于解决方案。
\n这是从零日期计算Libreoffice Calc的数字日期值所必需的。Libreoffice 中的零日期是1899-12-30。但是您必须从该日期倒数一天才能得到正确的解决方案,截至日期1899-12-29。发生这种情况是因为由于各种原因一天中的秒数并不恒定。例如从零日期1899-12-30 开始:
\n$ echo "( $(date +%s --date 2023-10-21) - $(date +%s --date 1899-12-30) ) / (3600*24)" | bc -l\n45219.97936342592592592592\nRun Code Online (Sandbox Code Playgroud)\n我们还需要 30 分 17 秒才能获得正确的整数 45220(对于我的时区)。\n对于不同的日期和时区,差异可能会有所不同。\n“所有这些意味着永远不应该处理依赖于date命令的计算作为整日,但也应考虑秒", - FedKad。\nLibreoffice 的零日期的更好计算可能如下所示(对浮点结果进行四舍五入):
\n$ echo "x=( $(date +%s --date 2023-10-21) - $(date +%s --date 1899-12-30) ) / (3600*24) + 0.5 ; scale=0; x/1" | bc -l\n45220\nRun Code Online (Sandbox Code Playgroud)\n感谢FedKad的回答。\n否则:对于某些时区,日期命令无法识别日期 19-10-01 的前 3 分 03 秒(尝试 " for i in {-1869875830..-1869875800}; do TZ=亚洲/伊斯坦布尔日期 --date @$i; 完成 ", - Egmont) 并计算零年,这是错误的;没有0年(FredKad)。
\n因此,“使用专用于日历日计算的工具”,- Egmont。
\n“对于(公历)公元1600 年之后的日期,您可以考虑使用dateutils.ddiff ”, \xe2\x80\x93 Steeldriver。
\n检查在线计算日期(FedKad)。
\nPS 要查看您所在国家/地区的时间差距,您可以使用“ zdump -v ”命令。例如:\nzdump -v 欧洲/柏林、zdump -v 美国/纽约、zdump -v 伊朗等。
\n我认为该date命令一开始就无法正确解释公元前年份:
date -d \'now - 2023 years\'is的输出是Fri 24 Nov 0000 02:58:34 PM LMT错误的;没有0年。
同样的date -d \'now - 2024 years\'输出也是Wed 24 Nov -001 03:00:16 PM LMT错误的。
即使您的问题()中的第一个计算结果45220也不正确,可以在线检查它返回45221天数。
我做了一些测试,发现该date命令似乎无法识别日期 1910-01-01 有效(至少对于我的时区):
$ date --date "1910-10-01"\ndate: invalid date \xe2\x80\x981910-10-01\xe2\x80\x99\nRun Code Online (Sandbox Code Playgroud)\n正如命令所示,这应该是星期六cal。
$ date --date "1910-09-30"\nFri 30 Sep 1910 12:00:00 AM IMT\n$ date --date "1910-09-31"\ndate: invalid date \xe2\x80\x981910-09-31\xe2\x80\x99\n$ date --date "1910-10-01"\ndate: invalid date \xe2\x80\x981910-10-01\xe2\x80\x99\n$ date --date "1910-10-02"\nSun 02 Oct 1910 12:00:00 AM EET\nRun Code Online (Sandbox Code Playgroud)\n@egmont 的评论中解释了这个“缺失一天”的原因(实际上是由于时区更改而缺失了 3 分 4 秒的时间段):
\n$ date --date "1910-09-30 23:59:59"\nFri 30 Sep 1910 11:59:59 PM IMT\n$ date --date "1910-10-01 00:00:00"\ndate: invalid date \xe2\x80\x981910-10-01 00:00:00\xe2\x80\x99\n$ date --date "1910-10-01 00:01:00"\ndate: invalid date \xe2\x80\x981910-10-01 00:01:00\xe2\x80\x99\n$ date --date "1910-10-01 00:03:03"\ndate: invalid date \xe2\x80\x981910-10-01 00:03:03\xe2\x80\x99\n$ date --date "1910-10-01 00:03:04"\nSat 01 Oct 1910 12:03:04 AM EET\nRun Code Online (Sandbox Code Playgroud)\n这就是您第一次计算中“缺失”这一天的原因。
\n请注意!在我的时区,您的计算给出:
\n$ echo $((($(date +%s --date "2023-10-21")-$(date +%s --date "1899-12-29"))/(3600*24)))\n45220\nRun Code Online (Sandbox Code Playgroud)\n上面的数字是除法浮点结果的“截断”整数结果,在我的时区中类似于 45220.9562037...。请检查您系统上以下命令的输出:
\n$ echo "( $(date +%s --date 2023-10-21) - $(date +%s --date 1899-12-29) ) / (3600*24)" | bc -l\n45220.95620370370370370370\nRun Code Online (Sandbox Code Playgroud)\n更好的计算可能是这样的(对浮点结果进行四舍五入):
\n$ echo "x=( $(date +%s --date 2023-10-21) - $(date +%s --date 1899-12-29) ) / (3600*24) + 0.5 ; scale=0; x/1" | bc -l\n45221\nRun Code Online (Sandbox Code Playgroud)\n所有这些意味着依赖date命令的计算永远不应该被视为整日,但也应该考虑秒数。
您可以使用其他工具:
\n$ dateutils.ddiff 1901-01-01 1601-01-01\n-109572\n$ dateutils.ddiff 1901-01-01 1600-12-31\nddiff: cannot make sense of `1600-12-31\' using the given input formats\nRun Code Online (Sandbox Code Playgroud)\nfrom datetime import date\nprint((date(2023,10,21)-date(1899,12,29)).days)\nRun Code Online (Sandbox Code Playgroud)\n您应该仔细考虑日期计算背后的实际需要,特别是对于公历没有意义的日期。
\n| 归档时间: |
|
| 查看次数: |
252 次 |
| 最近记录: |