The*_*Guy 3 bash shell-script date timestamps
我试图以 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
Run Code Online (Sandbox Code Playgroud)
但我收到这个错误。
date: invalid date ‘ 2021-08-07 15:00:00 + 30 minutes’
Run Code Online (Sandbox Code Playgroud)
您的特殊问题是+ 30被解释为无效的时区。
您可以通过在 UTC 时间工作来解决这个问题(这也可以避免 DST 更改带来的问题)并使用:
date -ud "$start_ts +0 + 30 minutes" +'%Y%m%d %T'
Run Code Online (Sandbox Code Playgroud)
(注意 +0 指定时区与 UTC 的偏移量为 0,因此下一个+30 minute被解释为偏移量)。
或者,为了仍然使用本地时间,插入today或now在时间戳之后,以确保以下内容被解释为偏移量:
date -d "$start_ts now + 30 minutes" +'%Y%m%d %T'
Run Code Online (Sandbox Code Playgroud)
虽然在这里,当您使用 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'
Run Code Online (Sandbox Code Playgroud)
避免date每个时间戳运行一个。请注意,这seq不是标准命令,但由于您拥有 GNU date,因此您还将拥有 GNU seq,它是同一 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
Run Code Online (Sandbox Code Playgroud)
请注意,这些可能会生成与您所在时区中的任何时间都不对应的时间戳。例如,在英国大陆这里,没有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)以使时间戳不含糊(假设您的时区偏移量始终是整个分钟数,现在到处都应该是这种情况)。