日期差异在UNIX
问题描述:
答
你可以试试下面的解决方案 -
[[email protected] ~]$ cat time.awk
{
diff1=((substr($1,1,4)) - (substr($2,1,4)))
diff2=((substr($1,5,2)) - (substr($2,5,2)))
if(diff1 > 0)
{
if(diff2 > 0)
{
print (diff1+diff2)
}
else if (diff2 = 0)
{
print (diff1+diff2)
}
else
{
diff2=(12+((substr($1,5,2)-(substr($2,5,2)))))
diff1=(diff1-1)
print (diff1+diff2)
}
}
else if(diff1 == 0)
{
if(diff2 > 0)
{
print (diff1+diff2)
}
else if (diff2 == 0)
{
print (diff1+diff2)
}
else
{
print "Argument 2 is greater than 1"
}
}
else
{
print "Argument 2 is greater than 1"
}
}
测试案例 -
[[email protected] ~]$ cat time1.txt && awk -f time.awk time1.txt
201611 201601
10
[[email protected] ~]$ cat time2.txt && awk -f time.awk time2.txt
201601 201611
Argument 2 is greater than 1
[[email protected] ~]$ cat time3.txt && awk -f time.awk time3.txt
201511 201601
Argument 2 is greater than 1
[[email protected] ~]$ cat time4.txt && awk -f time.awk time4.txt
201611 201611
0
答
时差的计算通常是一项复杂的工作,即使是单个日历类型(并且有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
实例一天24小时,一周7天,一年内为 年365.24225天,一年为12个月。
这间接证实了我关于任务复杂性的话。
然后让我们做同样的假设,并写了一个简单外壳脚本:
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
答
让我们尝试一些快速和肮脏的,不会对在历史上所有个月工作,但它可能不够好:转换到YYYYMM月数年以来0:
$ ym2m() {
if [[ $1 =~ ^([0-9]{4})([0-9]{2})$ ]]; then
echo $((10#${BASH_REMATCH[1]} * 12 + 10#${BASH_REMATCH[2]}))
else
return 1
fi
}
$ ym2m 201609
24201
$ ym2m 201508
24188
$ echo $(($(ym2m 201609) - $(ym2m 201508)))
13
注:
- 需要的bash版本4.3(我想)
-
ym2m
=>“年 - 月月” - 在算术表达式使用
10#number
,确保“08”和“09”不被视为无效的八进制数。
oldest_year_month_temp = 201602 NUM_PART_RETAIN = 20 oldest_year_month ='日期--date = “$(oldest_year_month_temp +%Y%M) - $ NUM_PART_RETAIN月”“+%Y%M'如何获得20个月旧的价值 –