Bash
在 2 個值之間生成時間戳
我試圖以 30 分鐘的間隔在 2 個時間戳值之間生成一個時間戳系列。
這是我已經準備好的。
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’
您的特殊問題是
+ 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
每個時間戳執行一個。請注意,這seq
不是標準命令,但是當您擁有 GNUdate
時,您還將擁有 GNUseq
,它是同一個 GNU 軟體包 (coreutils
) 的一部分。或者使用內置支持時間戳解析和格式化的 zsh shell,這將避免對 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 的時間戳將出現兩次。那天上面的程式碼仍然會在 00:30:00、01:00:00、01:30:00、02:00:00、02:30:00 迭代,而不會超過 01:00 -> 02 :00 間隔兩次。如果這不是您想要的,您應該刪除使其與 UTC 時間( 和 )一起工作的部分
-u
,+0
但是TZ=UTC0
您的格式應該包括時區偏移量 (%z
) 以使時間戳不模棱兩可(假設您的時區偏移量總是整分鐘數,現在到處都是這樣)。