shell – 基于yyymm在unix中的日期差异

#####DATE1=201609
#### DATE2=201508

如何计算这两个日期之间的差异并获得输出作为月份的计数

201609-201508=13month

最佳答案 即使对于单个日历类型(并且存在
many),时间差的计算通常是复杂的任务.许多编程语言都内置了对日期和时间操作操作的支持,包括计算时差.但是,流行的shell中最有用的功能是
date命令,遗憾的是缺少此功能.

因此,我们应该用另一种语言编写脚本,还是做出一些假设,例如一年中的天数.

例如,在Perl中,任务仅使用四行代码完成:

perl -e $(cat <<'PerlScript'
use Time::Piece;
my $t1 = Time::Piece->strptime($ARGV[0], '%Y%m');
my $t2 = Time::Piece->strptime($ARGV[1], '%Y%m');
printf "%d months\n", ($t1 - $t2)->months;
PerlScript
) 201609 201508

但是,Time :: Piece对象的区别是Time::Seconds的一个实例,它实际上假设了这一点

there are 24 hours in a day, 7 days in a week, 365.24225 days in a
year and 12 months in a year.

这间接证实了我关于任务复杂性的说法.

然后让我们做出相同的假设,并编写一个简单的shell脚本:

DATE1=201609
DATE2=201508

printf '(%d - %d) / 2629744.2\n' \
  $(date -d ${DATE1}01 +%s) \
  $(date -d ${DATE2}01 +%s) | bc

其中2629744.2是月份的秒数,即3600 * 24 *(365.24225 / 12).

注意,大多数shell不支持浮点运算.这就是为什么我们需要调用外部工具,如bc.

脚本输出13.这是一个便携版本.例如,您可以在标准shell,Bash,Korn shell或Zsh中运行它.如果要将结果放入变量中,只需将printf命令包装在$(…)中:

months=$(printf '(%d - %d) / 2629744.2\n' \
  $(date -d ${DATE1}01 +%s) \
  $(date -d ${DATE2}01 +%s) | bc)

printf '%d - %d = %d months\n' $DATE1 $DATE2 $months
点赞