A = “2002-20-10”
B =“2003-22-11”
如何找到两个日期之间的天数差异?
答案 0 :(得分:57)
bash方式 - 将日期转换为%y%m%d格式,然后您可以直接从命令行执行此操作:
echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
答案 1 :(得分:25)
如果你有GNU date
,它允许打印任意日期(-d
选项)的表示。
在这种情况下,将日期转换为自EPOCH以来的秒数,减去并除以24 * 3600。
或者您需要一种便携式方式?
答案 2 :(得分:16)
在python中
$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
答案 3 :(得分:16)
小心!这里的许多bash解决方案都被打破了日期范围,这些日期范围跨越了夏令时开始的日期(如果适用)。这是因为$((math))构造对结果值执行'floor'/ truncation操作,仅返回整数。让我来说明一下:
DST于今年3月8日在美国开始,所以让我们使用一个跨越的日期范围:
start_ts=$(date -d "2015-03-05" '+%s')
end_ts=$(date -d "2015-03-11" '+%s')
让我们看看我们用双括号得到的东西:
echo $(( ( end_ts - start_ts )/(60*60*24) ))
返回'5'。
使用'bc'更准确地执行此操作会给我们带来不同的结果:
echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc
返回'5.95' - 缺少的0.05是DST切换时的丢失小时数。
那么应该如何正确地完成呢? 我建议改用:
printf "%.0f" $(echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc)
这里,'printf'舍入'bc'计算的更准确的结果,给我们正确的日期范围'6'。
编辑:在@ hank-schultz的评论中突出显示答案,我最近一直在使用
date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s) )/(60*60*24) ))
只要您总是从后一个日期中减去较早的日期,这也应该是闰秒安全,因为闰秒只会增加差异 - 截断有效地向下舍入到正确的结果。
答案 4 :(得分:7)
以下是MAC OS X版本,以方便您使用。
$ A="2002-20-10"; B="2003-22-11";
$ echo $(((`date -jf %Y-%d-%m $B +%s` - `date -jf %Y-%d-%m $A +%s`)/86400))
的nJoy!
答案 5 :(得分:4)
如果选项-d在您的系统中有效,这是另一种方法。有一点需要注意的是,自从我每年考虑365天以来,它不会说明闰年。
date1yrs=`date -d "20100209" +%Y`
date1days=`date -d "20100209" +%j`
date2yrs=`date +%Y`
date2days=`date +%j`
diffyr=`expr $date2yrs - $date1yrs`
diffyr2days=`expr $diffyr \* 365`
diffdays=`expr $date2days - $date1days`
echo `expr $diffyr2days + $diffdays`
答案 6 :(得分:4)
即使您没有GNU日期,也可能安装了Perl:
use Time::Local;
sub to_epoch {
my ($t) = @_;
my ($y, $d, $m) = ($t =~ /(\d{4})-(\d{2})-(\d{2})/);
return timelocal(0, 0, 0, $d+0, $m-1, $y-1900);
}
sub diff_days {
my ($t1, $t2) = @_;
return (abs(to_epoch($t2) - to_epoch($t1))) / 86400;
}
print diff_days("2002-20-10", "2003-22-11"), "\n";
由于夏令时,这将返回398.041666666667
- 398天和1小时。
我的Feed反馈了这个问题。这是使用Perl捆绑模块
的更简洁方法days=$(perl -MDateTime -le '
sub parse_date {
@f = split /-/, shift;
return DateTime->new(year=>$f[0], month=>$f[2], day=>$f[1]);
}
print parse_date(shift)->delta_days(parse_date(shift))->in_units("days");
' $A $B)
echo $days # => 398
答案 7 :(得分:3)
这对我有用:
A="2002-10-20"
B="2003-11-22"
echo $(( ($(date -d $B +%s) - $(date -d $A +%s)) / 86400 )) days
打印
398 days
发生了什么事?
date -d
处理时间字符串date %s
将时间字符串转换为自1970年以来的秒数(unix epoche)答案 8 :(得分:2)
这是我使用zsh的工作方法。在OSX上测试过:
# Calculation dates
## A random old date
START_DATE="2015-11-15"
## Today's date
TODAY=$(date +%Y-%m-%d)
# Import zsh date mod
zmodload zsh/datetime
# Calculate number of days
DIFF=$(( ( $(strftime -r %Y-%m-%d $TODAY) - $(strftime -r %Y-%m-%d $START_DATE) ) / 86400 ))
echo "Your value: " $DIFF
结果:
Your value: 1577
基本上,我们使用strftime
反向(-r
)功能将日期字符串转换回时间戳,然后进行计算。
答案 9 :(得分:1)
我会在Ruby中提交另一个可能的解决方案。看起来它是迄今为止最小,最干净的一个:
A=2003-12-11
B=2002-10-10
DIFF=$(ruby -rdate -e "puts Date.parse('$A') - Date.parse('$B')")
echo $DIFF
答案 10 :(得分:1)
你应该安装GNU日期。你不需要偏离bash。考虑到几天,这里是解决方案,只是为了显示步骤。它可以简化并扩展到完整日期。
DATE=$(echo `date`)
DATENOW=$(echo `date -d "$DATE" +%j`)
DATECOMING=$(echo `date -d "20131220" +%j`)
THEDAY=$(echo `expr $DATECOMING - $DATENOW`)
echo $THEDAY
答案 11 :(得分:0)
命令行bash解决方案
echo $((($(date +%s -d 20210131)-$(date +%s -d 20210101))/86400)) days
将打印
30 days
答案 12 :(得分:0)
对于 zsh(仅适用于同一年的日期)
echo $(($(date -d "today" +%j) - $(date -d "08 Jan 2021" +%j) )) days
答案 13 :(得分:0)
我不想在生成自签名证书时将过期时间硬编码为设定的天数,而是想让它们在 Y2k38 problem 开始之前(2028 年 1 月 19 日)过期。但是,OpenSSL 只允许使用 -days
设置到期时间,即从当前日期算起的天数。
我最终使用了这个:
openssl req -newkey rsa -new -x509 \
-days $((( $((2**31)) - $(date +%s))/86400-1)) \
-nodes -out new.crt -keyout new.key -subj '/CN=SAML_SP/'
答案 14 :(得分:0)
echo $(date +%d/%h/%y) date_today
echo " The other date is 1970/01/01"
TODAY_DATE="1970-01-01"
BEFORE_DATE=$(date +%d%h%y)
echo "THE DIFFERNS IS " $(( ($(date -d $BEFORE_DATE +%s) - $(date -d $TODAY_DATE +%s)) )) SECOUND
使用它来获取您今天的日期以及您想要的日期之后的秒数。如果需要,只需将其除以86400
echo $(date +%d/%h/%y) date_today
echo " The other date is 1970/01/01"
TODAY_DATE="1970-01-01"
BEFORE_DATE=$(date +%d%h%y)
echo "THE DIFFERNS IS " $(( ($(date -d $BEFORE_DATE +%s) - $(date -d $TODAY_DATE +%s))/ 86400)) SECOUND
答案 15 :(得分:0)
这是我设法在centos 7上使用的最简单的方法:
OLDDATE="2018-12-31"
TODAY=$(date -d $(date +%Y-%m-%d) '+%s')
LINUXDATE=$(date -d "$OLDDATE" '+%s')
DIFFDAYS=$(( ($TODAY - $LINUXDATE) / (60*60*24) ))
echo $DIFFDAYS
答案 16 :(得分:0)
对于MacOS sierra(可能来自Mac OS X yosemate),
要从文件中获取纪元时间(1970年的秒数),并将其保存到var:
old_dt=`date -j -r YOUR_FILE "+%s"`
获取当前时间的纪元时间
new_dt=`date -j "+%s"`
计算上述两个纪元时间的差异
(( diff = new_dt - old_dt ))
检查差异是否超过23天
(( new_dt - old_dt > (23*86400) )) && echo Is more than 23 days
答案 17 :(得分:0)
这假设一个月是一年的1/12:
#!/usr/bin/awk -f
function mktm(datespec) {
split(datespec, q, "-")
return q[1] * 365.25 + q[3] * 365.25 / 12 + q[2]
}
BEGIN {
printf "%d\n", mktm(ARGV[2]) - mktm(ARGV[1])
}
答案 18 :(得分:0)
使用mysql命令
$ echo "select datediff('2013-06-20 18:12:54+08:00', '2013-05-30 18:12:54+08:00');" | mysql -N
结果:21
注意:在计算中仅使用值的日期部分
参考:http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_datediff
答案 19 :(得分:0)
假设我们手动将Oracle DB备份rsync到第三层磁盘。然后我们要删除该磁盘上的旧备份。所以这是一个小的bash脚本:
#!/bin/sh
for backup_dir in {'/backup/cmsprd/local/backupset','/backup/cmsprd/local/autobackup','/backup/cfprd/backupset','/backup/cfprd/autobackup'}
do
for f in `find $backup_dir -type d -regex '.*_.*_.*' -printf "%f\n"`
do
f2=`echo $f | sed -e 's/_//g'`
days=$(((`date "+%s"` - `date -d "${f2}" "+%s"`)/86400))
if [ $days -gt 30 ]; then
rm -rf $backup_dir/$f
fi
done
done
修改目录和保留期(“30天”)以满足您的需求。
答案 20 :(得分:0)
使用http://cfajohnson.com/shell/ssr/ssr-scripts.tar.gz中的shell函数;它们适用于任何标准的Unix shell。
date1=2012-09-22
date2=2013-01-31
. date-funcs-sh
_date2julian "$date1"
jd1=$_DATE2JULIAN
_date2julian "$date2"
echo $(( _DATE2JULIAN - jd1 ))
上的文档
答案 21 :(得分:0)
另一个Python版本:
python -c "from datetime import date; print date(2003, 11, 22).toordinal() - date(2002, 10, 20).toordinal()"
答案 22 :(得分:0)
尝试一下:
perl -e 'use Date::Calc qw(Delta_Days); printf "%d\n", Delta_Days(2002,10,20,2003,11,22);'