tec*_*ker 57
bash方式 - 将日期转换为%y%m%d格式,然后您可以直接从命令行执行此操作:
echo $(( ($(date --date="031122" +%s) - $(date --date="021020" +%s) )/(60*60*24) ))
Run Code Online (Sandbox Code Playgroud)
小智 29
如果你有GNU date
,它允许打印任意日期(-d
选项)的表示.在这种情况下,将日期转换为自EPOCH以来的秒数,减去并除以24*3600.
或者你需要一种便携式的方式?
Fre*_*ent 17
而在python中
$python -c "from datetime import date; print (date(2003,11,22)-date(2002,10,20)).days"
398
Run Code Online (Sandbox Code Playgroud)
eva*_*n_b 17
小心!这里的许多bash解决方案都被打破了日期范围,这些日期范围跨越了夏令时开始的日期(如果适用).这是因为$((math))构造对结果值执行'floor'/ truncation操作,仅返回整数.让我说明一下:
DST于今年3月8日在美国开始,所以我们使用的日期范围包括:
start_ts=$(date -d "2015-03-05" '+%s')
end_ts=$(date -d "2015-03-11" '+%s')
Run Code Online (Sandbox Code Playgroud)
让我们看看我们用双括号得到的东西:
echo $(( ( end_ts - start_ts )/(60*60*24) ))
Run Code Online (Sandbox Code Playgroud)
返回'5'.
使用'bc'更精确地执行此操作会给我们带来不同的结果:
echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc
Run Code Online (Sandbox Code Playgroud)
返回'5.95' - 缺少的0.05是DST切换时的丢失小时数.
那么应该如何正确完成呢?
我建议改用:
printf "%.0f" $(echo "scale=2; ( $end_ts - $start_ts )/(60*60*24)" | bc)
Run Code Online (Sandbox Code Playgroud)
在这里,'printf'舍入'bc'计算的更准确的结果,给我们正确的日期范围'6'.
编辑:在下面的@ hank-schultz的评论中突出显示答案,我最近一直在使用它:
date_diff=$(( ($(date -d "2015-03-11 UTC" +%s) - $(date -d "2015-03-05 UTC" +%s) )/(60*60*24) ))
Run Code Online (Sandbox Code Playgroud)
只要您总是从后一个日期中减去较早的日期,这也应该是闰秒安全,因为闰秒只会增加差异 - 截断有效地向下舍入到正确的结果.
jsc*_*sse 14
这对我有用:
A="2002-10-20"
B="2003-11-22"
echo $(( ($(date -d $B +%s) - $(date -d $A +%s)) / 86400 )) days
Run Code Online (Sandbox Code Playgroud)
印刷
398 days
Run Code Online (Sandbox Code Playgroud)
怎么了?
date -d
处理时间字符串date %s
时间转换字符串秒自1970年以来(UNIX悬搁)如果选项 -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`
Run Code Online (Sandbox Code Playgroud)
为方便起见,这是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))
Run Code Online (Sandbox Code Playgroud)
的nJoy!
即使您没有 GNU date,您也可能安装了 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";
Run Code Online (Sandbox Code Playgroud)
398.041666666667
由于夏令时,这将返回398 天零 1 小时。
这个问题又出现在我的提要上。这是使用 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
Run Code Online (Sandbox Code Playgroud)