快速计算日期差异

快速计算日期差异

我经常想要进行一些快速的日期计算,例如:

  • 这两个日期有什么区别?
  • 今天几号n另一个日期之后几周?

我通常打开日历并计算天数,但我认为应该有一个程序/脚本可以用来进行此类计算。有什么建议么?

答案1

使用 GNU date(1) 可以很容易地计算“约会后的 n 周”:

$ date -d 'now + 3 weeks'
Tue Dec  6 23:58:04 EST 2011
$ date -d 'Aug 4 + 3 weeks'
Thu Aug 25 00:00:00 EST 2011
$ date -d 'Jan 1 1982 + 11 weeks'
Fri Mar 19 00:00:00 EST 1982

我不知道计算两个日期之间差异的简单方法,但您可以使用 shell 函数在 date(1) 周围包装一些逻辑。

datediff() {
    d1=$(date -d "$1" +%s)
    d2=$(date -d "$2" +%s)
    echo $(( (d1 - d2) / 86400 )) days
}
$ datediff '1 Nov' '1 Aug'  # Note: answer should be 92 days but in my timezone, DST starts between the dates.
91 days

如果您想要以其他方式计算日期,请交换d1d2或者变得更花哨,使其变得无关紧要。此外,如果有非夏令时夏令时间隔过渡时,其中一天只有23小时长;您可以通过在总和中添加 ½ 天来进行补偿。

echo $(( (((d1-d2) > 0 ? (d1-d2) : (d2-d1)) + 43200) / 86400 )) days

答案2

对于一套便携式工具,请尝试我自己的日期工具。你的两个例子可以归结为一句话:

ddiff 2011-11-15 2012-04-11
=>
  148

或以周或天为单位:

ddiff 2011-11-15 2012-04-11 -f '%w %d'
=>
  21 1

dadd 2011-11-15 21w
=>
  2012-04-10

关于 Ubuntu 安装的重要说明:

这些完全相同的 dateutils 可用作Ubuntu 包,因此可以通过安装sudo apt install dateutils

但是,命令前面需要有前缀dateutils.,如dateutils.ddiff 2019-03-28 2019-05-16

它们还可以在 Fedora 和适用于 RHEL 的 Fedora EPEL 或带有sudo dnf install dateutils.在 Fedora 中,这些包不需要前缀,而是使用长名称 - 例如,datediffanddateadd代替ddiffand dadd

对于 Arch Linux,请安装带有sudo pacman -Sy dateutils.这些二进制文件称为datediffdateadd,就像在 Fedora 中一样。

答案3

计算我在地球上行走的天数的 python 示例:

$ python
>>> from datetime import date as D
>>> print (D.today() - D(1980, 6, 14)).days
11476

答案4

使用 获取出生日期(用于家谱)时出现此问题date -d "$death_date - $y years - $m months - $d days"。该命令是错误的。月份的长度并不完全相同,因此(date + offset) - offset != date。以年/月/日为单位的年龄是从出生日期开始的测量值。

$ date --utc -d 'mar 28 1867 +72years +11months +2days'
Fri Mar  1 00:00:00 UTC 1940

$ date --utc -d 'mar 1 1940 -72years -11months -2days'
Sat Mar 30 00:00:00 UTC 1867
# (2 days later than our starting point)

Date 在这两种情况下都给出了正确的输出,但在第二种情况下,您提出了错误的问题。在添加/减去天数之前,+/- 11 涵盖一年中的哪 11 个月很重要。例如:

$ date --utc -d 'mar 31 1939  -1month'
Fri Mar  3 00:00:00 UTC 1939
$ date --utc -d 'mar 31 1940  -1month' # leap year
Sat Mar  2 00:00:00 UTC 1940
$ date --utc -d 'jan 31 1940  +1month' # leap year
Sat Mar  2 00:00:00 UTC 1940

为了使减法成为加法的逆运算,必须颠倒运算顺序。添加添加年,然后添加月,然后添加天。如果减法使用相反的顺序,那么您将回到起点。它不会,所以如果天数偏移在不同长度的月份中跨越月份边界,则您不会。

如果您需要从结束日期和年龄开始向后工作,您可以通过多次调用 来完成date。首先减去天数,然后减去月份,然后减去年份。 (我认为在一次调用中组合年份和月份是不安全的date,因为闰年​​会改变二月的长度。)

相关内容