以自定義格式減去日期
我需要從目前日期中減去某個日期以確定某些連接的年齡。日期格式如下:
YYMMDDHHMISS
. 輸出幾乎可以是任何我可以用來確定的東西,比如說最舊的連接、超過 1 小時、1 週、1 個月的連接數。輸入日期範例:
211013134247
我已經到了從
date
命令(date '+%g%m%d%H%M%S'
)中以這種格式獲取日期的地步,但我不知道如何正確減去它以獲得準確的結果。我試過這個,但是一旦連接日期的一個數字(如秒)大於目前日期,就會出現問題。範例:連接的秒數為 53,目前秒數為 47。
$ line = connection 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 開頭的日期……也許(幾乎可以肯定)我這樣做完全錯誤,而且這樣做的方法要簡單得多。
我在 2 小時內將這個問題拼湊在一起,所以如果有什麼不合理的地方,請指出,我會盡力解決它。
在
zsh
:zmodload zsh/datetime timestamp=211013134247 strftime -rs t %y%m%d%H%M%S $timestamp print $(( EPOCHSECONDS - t ))
請注意,這
%g
是 iso 週年份,而不是您要查找的內容。例如,在 2021 年 1 月 1 日(這裡使用 GNU 實現date
for that non-standard-d
):$ date -d 2021-01-01 +%gW%V-%A 20W53-Friday
這是 ISO 2020 年第 53 週的星期五,因為該週在 2020 年的天數比 2021 年多,所以它被算作 2020 年的一周,而不是 2021 年的一周。
您只想將
%g
/%G
與%V
(ISO 週數)結合使用。%y
/%Y
是目前年份。標準
date
不支持解析日期並重新格式化它們以輸出(而不是設置系統時間)。其中一些以不同且不兼容的方式支持將其作為擴展。在那些這樣做的人中,大多數實現都支持在strptime()
style 中指定輸入格式(如上面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