使用 Linux“date”命令构建每天 6 小时的日期系列(每天 4 个时间步长)

使用 Linux“date”命令构建每天 6 小时的日期系列(每天 4 个时间步长)

我正在尝试构建一个“N”年的每日 6 小时日期系列。我尝试这样做

for i in {1..1825}; do 
date -d "00:00 01-01-1998 +6 hours" +"%d-%m-%Y %H:%M"
done

但这不是我想要的。

我的目标是按顺序创建这样的;

01-01-1998 00:00 
01-01-1998 06:00 
01-01-1998 12:00 
01-01-1998 18:00 
02-01-1998 00:00 
02-01-1998 06:00
02-01-1998 12:00 
02-01-1998 18:00 
.
.
.etc

我怎样才能使用date命令来做到这一点?

非常感谢任何帮助。提前致谢。

答案1

您必须担心夏令时。例如,我的时区是加拿大/东部,并且:

$ d=$(date -d "2020-03-08 00:00:00")
$ echo $d
Sun Mar 8 00:00:00 EST 2020
$ d=$(date -d "$d + 6 hours")
$ echo $d
Sun Mar 8 07:00:00 EDT 2020
# ........^^

$ d=$(date -d "2020-11-01 00:00:00")
$ echo $d
Sun Nov 1 00:00:00 EDT 2020
$ d=$(date -d "$d + 6 hours")
$ echo $d
Sun Nov 1 05:00:00 EST 2020
# ........^^

确保为时区指定 UTC。

$ d=$(date -u -d "2020-11-01 00:00:00")
$ echo $d
Sun Nov 1 00:00:00 UTC 2020
$ d=$(date -u -d "$d + 6 hours")
$ echo $d
Sun Nov 1 06:00:00 UTC 2020
# ........^^

所以:

fmt='%d-%m-%Y %H:%M'
d=$(date -u -d "1998-01-01 00:00:00")
for i in {1..1825}; do 
    # print the current date
    date -u -d "$d" "+$fmt"
    # add 6 hours
    d=$(date -u -d "$d + 6 hours")
done

我强烈建议您使用 ISO 日期格式 YYYY-mm-dd:这是一种明确的日期格式,并且按词汇和时间顺序排序。

答案2

您可以将每次计算的日期保存在变量中,并用它来计算下一个日期。我使用标准区域设置中的默认格式来存储日期,因为date无法解析您指定的格式。

# start date
d=$(LC_ALL=C date -d "1998-01-01 00:00")
echo "# d=$d"
# convert format
date -d "$d" +"%d-%m-%Y %H:%M"

for i in {1..1825}; do 
    # add 6 hours
    d=$(LC_ALL=C date -d "$d +6 hours")
    # convert format
    date -d "$d" +"%d-%m-%Y %H:%M"
done

这打印

# d=Thu Jan  1 00:00:00 CET 1998
01-01-1998 00:00
01-01-1998 06:00
01-01-1998 12:00
01-01-1998 18:00
02-01-1998 00:00
02-01-1998 06:00
02-01-1998 12:00
02-01-1998 18:00
03-01-1998 00:00
03-01-1998 06:00
03-01-1998 12:00
03-01-1998 18:00
04-01-1998 00:00
04-01-1998 06:00
...

结果取决于您所在的时区和夏令时规则。

您的开始时间指定可能不明确,因为它没有指定时区。

编辑基于保罗学究的评论:

创建 + $i 天的外循环,以及硬编码的内循环 00, 06, 12, 18。它运行四分之一的日期进程,并且不关心 DST 变化。

# start date
d=$(LC_ALL=C date -d "1998-01-01 00:00")
echo "# d=$d"

for i in {1..456}; do 
    # convert (partial) format
    out=$(date -d "$d" +"%d-%m-%Y")
    for h in 00 06 12 18; do
        echo "$out $h:00"
    done
    # add 1 day
    d=$(LC_ALL=C date -d "$d +1 day")
done

请在问题中具体说明在正常时间和夏令时之间切换时您期望的结果。 (严格打印 00:00、06:00、12:00、18:00 或切换 DST 时正好 6 小时时差)

编辑基于格伦·杰克曼回答

-u向所有调用添加选项date将使脚本与 Glenn jackman 编写的脚本几乎相同,并导致严格打印 00:00、06:00、12:00、18:00,无论夏令时如何。

答案3

使用 GNU,date您可以在起点上添加不断增加的小时数

start="$(date +'%Y-%m-%d')"
for i in {0..1825}
do
    date --date "$start +$((i*6)) hours" +'%d-%m-%Y %H:%M'
done

六个小时的间隔保持不变,但由于我所在的地区(英国时区),实际时间由于夏令时和冬令时之间的切换而发生变化。

24-10-2020 00:00
24-10-2020 06:00
24-10-2020 12:00
24-10-2020 18:00
25-10-2020 00:00
25-10-2020 05:00    ← Six hours on from midnight because the clock goes back one hour at 03:00
25-10-2020 11:00
25-10-2020 17:00
25-10-2020 23:00

您的问题中没有指定您是否希望时间间隔为午夜、上午 6 点、中午和下午 6 点(无论夏季/冬季时间之间是否有任何可能的切换),或者您希望时间间隔固定为精确的六小时间隔。

使用date --utc而不只是date保证生成一系列看起来相隔六个小时的日期时间,而不考虑时区。

相关内容