2 つの ISO8601 日付間の時間差 (秒の小数部を含む)

2 つの ISO8601 日付間の時間差 (秒の小数部を含む)

Alpine Linux から次のタイムスタンプを受け取ります。

2017-04-25T07:19:53.946109551Z    
2017-04-25T07:19:53.946155414Z

どうすればそれらを解読し、その間にどれくらいの時間が経過したかを知ることができるのでしょうか?

リンクされた質問ではエポックタイムについて言及されていますが、ここでは明らかにそうではありません。

答え1

GNU システムの場合:

d1=2017-04-25T07:19:53.946109551Z
d2=2017-04-25T07:19:53.946155414Z
printf '%s - %s\n' "$(date -d "$d2" +%s.%N)" "$(date -d "$d1" +%s.%N)" | bc

時間差を浮動小数点数秒として返します。

注意: 小数点区切り文字としてコンマ ( ) が使用されるロケールでも、数値は.ピリオド ( ,) を使用して示されます。

この出力をパイプしてtr . "$(locale decimal_point)"修正することができます。

または、 を使用するとzsh、次のように実行できます。

printf '%.9f\n' $(($(date -d "$d2" +%s.%N) - $(date -d "$d1" +%s.%N)))

代わりに、ロケールの正しい小数点区切り文字が付いた数値が返されます。

ただし、プロセッサの数値形式zshが使用されるため、数値がその数値の精度の限界に達するdoubleと、異なる数値が返される場合があります。任意の精度を使用するため、問題は発生しません。1493104793.946109551bc

zsh時間解析機能が組み込まれているため、次のような非 GNU システムでも動作するソリューションを作成することもできます。

parse_iso8601_full() {
  local t
  typeset -Fg REPLY
  zmodload zsh/datetime
  TZ=UTC0 strftime -r -s t %Y-%m-%dT%H:%M:%S ${1%.*} &&
    REPLY=$t.${${1%Z}##*.}
}

parse_iso8601_full $d1; t1=$REPLY
parse_iso8601_full $d2; t2=$REPLY
printf '%.9f\n' $((t2 - t1))

関連情報