カスタム形式に日付を減算する

カスタム形式に日付を減算する

一部の接続の寿命を確認するには、現在の日付から一部の日付を減算する必要があります。日付形式は次のとおりですYYMMDDHHMISS。出力は、最も古い接続、1時間、1週間、1ヶ月より古い接続数などを確認するために使用できるほぼすべてのものにすることができます。

日付入力の例:211013134247

datecommand( ) でこの形式の日付を取得しましたが、date '+%g%m%d%H%M%S'正確な結果を得るためにそれを正しく減算する方法がわかりません。


これを試しましたが、リンクされた日付の数(秒など)の1つが現在の日付より大きいとすぐに問題が発生します。例: 接続秒は 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年から始まらない日付に変換する方法がわかりません...


たぶん(ほぼ確実に)私がこれを完全に間違っているのかもしれないし、より簡単な方法があるかもしれません。
この内容を整理するのに2時間以上かかりました。理解できない部分があれば指摘していただければ修正するよう努力いたします。

ベストアンサー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駐車場金曜日であり、その週は2021年より2020年に日数が多いため、2021年に1週間ではなく2020年に1週間と計算されます。

(ISO週番号)のみ%g/を使用したいです。 /は現在の年です。%G%V%y%Y

標準は、date日付の解析と出力のためのフォーマットの再指定(システム時間設定の代わりに)をサポートしていません。そのうちのいくつかは、異なる互換性のない方法で拡張機能をサポートしています。これを行う実装のほとんどはstrptime()(上記zshstrftime組み込みのような-r)スタイルで入力フォーマットを指定することをサポートしており、GNUはdate注目に値する例外です。

  • ast-open datedate(コンパイル時に有効になっている場合は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タイムスタンプをサポートされている形式の1つに変換する必要があります。

標準 2021-10-13T13:42:47 形式にすることができます。

$ timestamp=211013134247
$ date -d "20$(echo "$timestamp" | fold -w2 | paste -sd--T::)" +"%s"
1634128967

(年が2000年から2099年までであると仮定します。)

または、次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

おすすめ記事