2つの値の間のタイムスタンプの生成

2つの値の間のタイムスタンプの生成

2つのタイムスタンプ値の間に30分間隔でタイムスタンプシリーズを作成しようとしています。

これが私が準備したものです。

start_ts='2021-08-07 15:00:00'
end_ts='2021-08-11 05:00:00'

while ! [[ $start_ts > $end_ts ]]; do
    echo $start_ts
    start_ts=$(date -d "$start_ts + 30 minutes" +"%Y%m%d% H%:%M:%S")
done

ただし、このエラーが発生します。

date: invalid date ‘ 2021-08-07 15:00:00 + 30 minutes’

ベストアンサー1

特定の問題は、+ 30無効と解釈される時間帯です。

UTC 時間 (DST 変更の問題を回避) を使用してこの問題を解決し、次を使用できます。

date -ud "$start_ts +0 + 30 minutes" +'%Y%m%d %T'

(+0 は UTC でタイムゾーンオフセット 0 を指定するため、次は+30 minuteオフセットとして解釈されます.)

または、現地時間を引き続き使用するには、タイムスタンプの後にtodayまたはを挿入して、後続nowの内容がオフセットとして解釈されるようにします。

date -d "$start_ts now + 30 minutes" +'%Y%m%d %T'

ここでGNU固有の拡張機能を使用すると、次のことができます。

start_ts=$(date -ud '2021-08-07 15:00:00' +%s)
end_ts=$(date -ud '2021-08-11 05:00:00' +%s)

seq -f "@%.0f" "$start_ts" "$((30 * 60))" "$end_ts" |
  date -uf - +'%Y%m%d %T'

dateタイムスタンプごとに1つずつ実行されるのを防ぎます。これはseq標準コマンドではありませんが、GNUがある場合は、同じGNUパッケージ()の一部であるGNUdateもあります。seqcoreutils

または、タイムスタンプの解析と書式設定をデフォルトでサポートするzshシェルを使用すると、GNUへの依存関係を回避できますdate

#! /bin/zsh -
zmodload zsh/datetime

format='%Y%m%d %T'
TZ=UTC0 strftime -rs start_ts $format '20210807 15:00:00'
TZ=UTC0 strftime -rs end_ts   $format '20210811 05:00:00'
for ((t = start_ts; t <= end_ts; t += 30 * 60))
  TZ=UTC0 strftime $format $t

これは、タイムゾーンの特定の時間と一致しないタイムスタンプを生成できることに注意してください。たとえば、ここイギリス本土では、その日の夏時間に切り替えると、2021-03-28 01:30:00壁時計は00:59:59.99から02:00:00.00にすぐに移動します。代わりに、2021年10月31日には01:00:00から02:00:00までのタイムスタンプが2回表示されます。上記のコードは、01:00 - > 02:00を超えず、その日付の00:30:00、01:00:00、01:30:00、02:00:00、02:30:00で繰り返しになります。二度間隔をあけた。

これが望ましくない場合は、UTC時間(および-u)で動作させる部分を削除する必要があります+0TZ=UTC0ただし、タイムスタンプがあいまいにならないように、フォーマットにはタイムゾーンオフセット(%z)を含める必要があります(タイムゾーンオフセットは常に数分かかります。現在どこでもそうです)。

おすすめ記事