
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
もあります。seq
coreutils
または、タイムスタンプの解析と書式設定をデフォルトでサポートする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
)で動作させる部分を削除する必要があります+0
。TZ=UTC0
ただし、タイムスタンプがあいまいにならないように、フォーマットにはタイムゾーンオフセット(%z
)を含める必要があります(タイムゾーンオフセットは常に数分かかります。現在どこでもそうです)。