Linux

以自定義格式減去日期

  • October 13, 2021

我需要從目前日期中減去某個日期以確定某些連接的年齡。日期格式如下: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 實現datefor 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 中指定輸入格式(如上面zshstrftime內置-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

引用自:https://unix.stackexchange.com/questions/673062