我正在尝试构建一个“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
保证生成一系列看起来相隔六个小时的日期时间,而不考虑时区。