cam*_*amh 143
使用 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
Run Code Online (Sandbox Code Playgroud)
我不知道计算两个日期之间差异的简单方法,但是您可以使用 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
Run Code Online (Sandbox Code Playgroud)
交换d1
,d2
如果你想以另一种方式计算日期,或者变得更有趣,让它无关紧要。此外,如果间隔中有非 DST 到DST 的转换,其中一天将只有 23 小时;您可以通过在总和上增加 ½ 天来补偿。
echo $(( (((d1-d2) > 0 ? (d1-d2) : (d2-d1)) + 43200) / 86400 )) days
Run Code Online (Sandbox Code Playgroud)
hro*_*tyr 55
对于一组便携式工具,请尝试我自己的dateutils。你的两个例子可以归结为单行:
ddiff 2011-11-15 2012-04-11
=>
148
Run Code Online (Sandbox Code Playgroud)
或以周和天为单位:
ddiff 2011-11-15 2012-04-11 -f '%w %d'
=>
21 1
Run Code Online (Sandbox Code Playgroud)
和
dadd 2011-11-15 21w
=>
2012-04-10
Run Code Online (Sandbox Code Playgroud)
关于 Ubuntu 安装的重要说明:
这些非常相同的 dateutils 可作为Ubuntu 软件包使用,因此可以通过sudo apt install dateutils
.
但是,命令前面需要有dateutils.
前缀,如dateutils.ddiff 2019-03-28 2019-05-16
它们也可以在 Fedora 和 Fedora EPEL for RHEL 或 CentOS 中使用sudo dnf install dateutils
。在 Fedora 中,这些包不需要前缀而是使用长名称——例如,datediff
anddateadd
代替ddiff
and dadd
。
对于 Arch Linux,使用sudo pacman -Sy dateutils
. 二进制文件被称为datediff
and dateadd
,就像在 Fedora 中一样。
Dan*_*und 36
用于计算我在地球上行走的天数的 Python 示例:
$ python
>>> from datetime import date as D
>>> print (D.today() - D(1980, 6, 14)).days
11476
Run Code Online (Sandbox Code Playgroud)
Mat*_*nco 15
我通常更喜欢 unix utime 格式的时间/日期(自七十年代开始的纪元以来的秒数,UTC)。这样它总是归结为简单的减法或加法秒。
问题通常是将日期/时间转换为这种格式。
在 shell 环境/脚本中,您可以使用date '+%s'
在撰写本文时,当前时间为1321358027
.
与 2011-11-04(我的生日)相比,date '+%s' -d 2011-11-04
, yield 1320361200
。减去:expr 1321358027 - 1320361200
给出996827
秒,即expr 996827 / 86400
= 11 天前。
使用标准库将 utime(1320361200 格式)转换为日期非常简单,例如在 C、PHP 或 perl 中。对于 GNU date
,-d
可以在参数前面加上@
“自纪元以来的秒数”格式。
Pet*_*des 10
这是在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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
为了使减法成为加法的逆运算,必须颠倒运算顺序。添加会增加年,然后是月,然后是天。如果减法使用相反的顺序,那么您将回到起点。如果天数偏移量在不同长度的月份中跨越月份边界,则不会,因此您不会。
如果您需要从结束日期和年龄向后工作,您可以通过多次调用date
. 先减去天数,然后减去月数,然后减去年数。(我认为在一次date
调用中组合年份和月份是不安全的,因为闰年会改变二月的长度。)
如果图形工具适合你,我衷心推荐qalculate
(一个强调单位转换的计算器,它带有一个 GTK 和 KDE 界面,IIRC)。在那里你可以说例如
days(1900-05-21, 1900-01-01)
Run Code Online (Sandbox Code Playgroud)
获取日期之间的天数(140,因为 1900 年不是闰年),但当然您也可以对时间执行相同的操作:
17:12:45 ? 08:45:12
Run Code Online (Sandbox Code Playgroud)
产生8.4591667
小时,或者,如果您将输出设置为时间格式,则8:27:33
.
小智 5
您可以使用另一种方法来计算同一日历年的两个日期之间的差异:
date_difference.sh
1 #!/bin/bash
2 DATEfirstnum=`date -d "2014/5/14" +"%j"`
3 DATElastnum=`date -d "12/31/14" +"%j"`
4 DAYSdif=$(($DATElastnum - $DATEfirstnum))
5 echo "$DAYSdif"
Run Code Online (Sandbox Code Playgroud)
date
变量 DATEfirstnum。该-d
标志以时间格式显示字符串(在本例中为 2014 年 5 月 14 日),并+"%j"
指示date
将输出格式设置为一年中的某一天 (1-365)。DAYSdif
两天的差值。DAYSdif
。这适用于 GNU 版本的date
,但不适用于 PC-BSD/FreeBSD 版本。我coreutils
从 ports 树安装并使用命令/usr/local/bin/gdate
。
在丹纳斯解决方案的帮助下,这可以通过以下代码一行完成:
python -c "from datetime import date as d; print(d.today() - d(2016, 7, 26))"
Run Code Online (Sandbox Code Playgroud)
(适用于 Python 2.x 和 Python 3。)