我需要从当前日期中减去一些日期来确定某些连接的年龄。日期的格式如下:YYMMDDHHMISS
。输出几乎可以是我可以用来确定的任何内容,例如最旧的连接、超过 1 小时、1 周、1 个月的连接数。
输入日期示例:211013134247
我已经从date
命令 ( date '+%g%m%d%H%M%S'
) 获取这种格式的日期,但我不知道如何正确减去它以获得准确的结果。
我尝试了这个,但是一旦连接日期中的一个数字(如秒)大于当前日期,就会出现问题。示例:连接秒数为 53,当前秒数为 47。
$line = 连接日期
$date = 当前日期
year= $((${date:0:2} - ${line:0:2}))
month= $((${date:2:2} - ${line:2:2}))
day= $((${date:4:2} - ${line:4:2}))
hour= $((${date:6:2} - ${line:6:2}))
minute= $((${date:8:2} - ${line:8:2}))
second= $((${date:10:2} - ${line:10:2}))
age=$year$month$day$hour$minute$second
我也尝试过这个(一些代码无耻地从堆栈交换中窃取),但输出是错误的。我期望类似:0607********
,如6年7个月等。输入日期通常不应相隔数年,因此年份计算可以被排除在外。
date="211013150325"
line="150325113419"
convert_date(){ printf `date '+%C'`'%s-%s-%s %s:%s:%s' ${1:0:2} ${1:2:2} ${1:4:2} ${1:6:2} ${1:8:2} ${1:10:2}; }
diff_dates(){
TS1=$(date -d "$1" +%s)
TS2=$(date -d "$2" +%s)
TZ=UTC date -d @$((TS1-TS2)) +%g%m%d%H%M%S
#+%Y.%m.%d.%H:%M:%S
}
date_converted=`convert_date $date`
echo $date_converted
line_converted=`convert_date $line`
echo $line_converted
diff_dates $date_converted $line_converted
root@SomeHost:~# date="211013150325"
root@SomeHost:~# line="150325113419"
root@SomeHost:~# convert_date(){ printf `date '+%C'`'%s-%s-%s %s:%s:%s' ${1:0:2} ${1:2:2} ${1:4:2} ${1:6:2} ${1:8:2} ${1:10:2}; }
root@SomeHost:~# diff_dates(){
> TS1=$(date -d "$1" +%s)
> TS2=$(date -d "$2" +%s)
> TZ=UTC date -d @$((TS1-TS2)) +%g%m%d%H%M%S
> #+%Y.%m.%d.%H:%M:%S
> }
root@SomeHost:~#
root@SomeHost:~# date_converted=`convert_date $date`
root@SomeHost:~# echo $date_converted
2021-10-13 15:03:25
root@SomeHost:~# line_converted=`convert_date $line`
root@SomeHost:~# echo $line_converted
2015-03-25 11:34:19
root@SomeHost:~# diff_dates $date_converted $line_converted
701231085635
我可以删除TZ=UTC date -d @$((TS1-TS2)) +%g%m%d%H%M%S
并使用其他东西获得更好的转化吗?我可以得到以echo $(($TS2-$TS1))
秒为单位的时间,但我不知道如何将其转换为不以 1970 年开头的日期......
也许(几乎可以肯定)我这样做是完全错误的,并且有更简单的方法可以做到这一点。
我花了两个多小时把这个问题拼凑起来,所以如果有什么地方没有意义,请指出,我会尽力解决它。
答案1
在zsh
:
zmodload zsh/datetime
timestamp=211013134247
strftime -rs t %y%m%d%H%M%S $timestamp
print $(( EPOCHSECONDS - t ))
请注意,这%g
是 iso 周年,而不是您要寻找的。例如,2021 年 1 月 1 日(这里是date
该非标准的 GNU 实现-d
):
$ date -d 2021-01-01 +%gW%V-%A
20W53-Friday
这是 2020 年 ISO 第 53 周的星期五,因为该周 2020 年的天数多于 2021 年的天数,因此被算作 2020 年的一周,而不是 2021 年的一周。
您只想将%g
/%G
与%V
(ISO 周数)结合使用。%y
/%Y
是当前年份。
标准date
不支持解析日期并重新格式化它们以进行输出(而不是设置系统时间)。他们中的一些人以不同且不兼容的方式支持将其作为扩展。在那些这样做的实现中,大多数实现都支持在 style 中指定输入格式strptime()
(如上面zsh
的strftime
内置-r
),但 GNUdate
是一个值得注意的例外。
ast-open
date
date
(如果在编译时启用,也是 ksh93 的内置命令):$ date -p %y%m%d%H%M%S -d 211013134247 +%FT%T%z 2021-10-13T13:42:47+0100 $ date -p %y%m%d%H%M%S -d 211013134247 +%s 1634128967
busybox
date
:$ date -D '%y%m%d%H%M%S' -d 211013134247 +%FT%T%z 2021-10-13T13:42:47+0100 $ date -D '%y%m%d%H%M%S' -d 211013134247 +%s 1634128967
BSD
date
:$ date -jf %y%m%d%H%M%S 211013134247 +%FT%T%z 2021-10-13T13:42:47+0100 $ date -jf %y%m%d%H%M%S 211013134247 +%s 1634128967
对于 GNU date
,您需要将时间戳转换为其支持的格式之一。
可以是标准 2021-10-13T13:42:47 格式:
$ timestamp=211013134247
$ date -d "20$(echo "$timestamp" | fold -w2 | paste -sd--T::)" +"%s"
1634128967
(假设年份仅为 2000 年至 2099 年)。
或者使用现在一些 shell 支持的ksh93
-style ,包括:${param:offset:length}
bash
$ date -d "20${t:0:2}-${t:2:2}-${t:4:2}T${t:6:2}:${t:8:2}:${t:10:2}" +%s
1634128967
答案2
我可以得到以
echo $(($TS2-$TS1))
秒为单位的时间,但我不知道如何将其转换为日期
您可以使用以下命令将秒转换为小时、分钟、秒:
date -d@$SECVAR -u +%H:%M:%S
其中变量SECVAR
包含秒