生成 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被解释为偏移量)。

或者,要仍然使用本地时间,请在时间戳之后插入todaynow,以确保后面的内容被解释为偏移量:

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不是一个标准命令,但是当您拥有 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

请注意,这些可能会生成与您所在时区的任何时间都不对应的时间戳。例如,在英国大陆这里,没有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+0TZ=UTC0但您的格式应包含时区偏移量 ( %z) 以使时间戳不模糊(假设您的时区偏移量始终为整整几分钟,现在到处都是这种情况)。

相关内容