如何对 24 小时循环进行排序,例如 .. 22 23 00 01

Ale*_*eds 3 bash shell-script

我只需要输出指定的小时数(例如 8 小时)并根据 UTC 时区更改转移时间点。

我想看到的输出是:

Athens     15 16 17 18 19 20 21 22 (+2)
Hong_Kong  21 22 23 00 01 02 03 04 (+8)
Run Code Online (Sandbox Code Playgroud)

我正在玩弄date命令,并在 SuperUser 上发现了这个有趣的代码。对我来说有很多东西要学。我根据自己的需要调整了它。但是,我发现时区更改存在逻辑问题:循环不断增加时间超出 24 小时范围。因此,它打印的不是上面的示例:

Athens     15 16 17 18 19 20 21 22 (+2)
Hong_Kong  21 22 23 24 25 26 27 28 (+8)
Run Code Online (Sandbox Code Playgroud)

这显然是错误的。

该代码使用带有排序的嵌套循环。对于我的一生,我无法弄清楚如何将小时的范围限制为 24 位数字。

这是作者代码中发生的事情的粗略想法。如何防止循环超过24小时并从23点循环到00点?

Athens     15 16 17 18 19 20 21 22 (+2)
Hong_Kong  21 22 23 00 01 02 03 04 (+8)
Run Code Online (Sandbox Code Playgroud)

输出

%
City-1  14 15 16 17 18 19 20 21 22 23 24 25 26  
City-2  14 15 16 17 18 19 20 21 22 23 24 25 26 
Run Code Online (Sandbox Code Playgroud)

PS 上面的示例没有显示时间线中的时区变化。我只是不知道如何执行它。

ilk*_*chu 5

您的脚本无法运行,因为点 in 在timediff[$tz]=6.仅支持整数运算的 Bash 中不起作用。

不管怎样,如果你想让序列变成 22, 23, 0, 1, ...,这个概念就是模算术,类 C 语言中的运算符是%。例如

for i in 1 2 3 4 5; do
    echo $(( i % 3 ))
done
Run Code Online (Sandbox Code Playgroud)

印刷1 2 0 1 2% 24当然,对于小时数,您会使用。当然,用户需要知道显示的时间是哪一天。例如,这将从 UTC+0200 转换为 UTC+1200

mytz=2 othertz=12
for h in {8..16}; do
    printf "%02d ($mytz) == %02d ($othertz)\n" "$h" "$(( (h - mytz + othertz) % 24))";
done
Run Code Online (Sandbox Code Playgroud)

给予08 (+2) == 18 (+12)

如果您知道时区的正确文件名,您还可以使用环境date变量进行翻译。TZ此处使用 GNU 日期:

hour=08
tz=Asia/Hong_Kong
printf "local: %s\nother: %s\n" "$(date +"%F %T %Z (%z)" -d "@$ts")" "$(TZ=$tz date +"%F %T %Z (%z)" -d "@$ts")"
Run Code Online (Sandbox Code Playgroud)

输出:

for i in 1 2 3 4 5; do
    echo $(( i % 3 ))
done
Run Code Online (Sandbox Code Playgroud)