修复 %(%H)T 给出 12 小时的问题

修复 %(%H)T 给出 12 小时的问题

我正在传递一个时间间隔(以秒为单位)ts

ts=13
printf -v hours '%(%H)T' "$ts"
printf '%s\n' "ts: $ts ; hours: $hours"

这是不正确的结果。

时间:13;小时:12

正如您所看到的,我得到的12不是0013 秒。

答案1

正如评论中所讨论的,我认为你的问题是时区。%(...)T以当地时间打印时间,所以例如我得到

$ printf "%(%F %T %z)T\n" "$(date +%s)"
2021-08-21 19:58:45 +0300

但您应该能够设置TZ变量来更改时区:

$ TZ=UTC printf "%(%F %T %z)T\n" "$(date +%s)"
2021-08-21 16:59:45 +0000

特别是,参数是纪元之后的秒数,即 1970 年 1 月 1 日 00:00:00 UTC 之后。这是一个时间点,而不是一个时间间隔。但是,如果我们稍微眯一下眼睛,确保使用 UTC(因此时区并不重要),并忽略年份,我们可以将其视为足够小的值的间隔长度。

说明strftime()%j会给出一年中的第几天,介于 001 和 366 之间,因此将其与 一起使用%H %M %S,我们可以获得天、小时、分钟和秒,最多可达一年。请注意,天数中有 1 的偏移量:

$ TZ=UTC printf "%(%j %H %M %S)T\n" "$(( 123*86400 + 7*3600 + 6*60 + 5))"
124 07 06 05

或者,通过一些 eval 技巧,这会将值分配给变量:

$ eval "$(TZ=UTC printf "%(daysplus1=%j hours=%H mins=%M secs=%S)T" \
                        "$(( 123*86400 + 7*3600 + 6*60 + 5))" )"
$ days=$((daysplus1 - 1))
$ echo $days $hours $mins $secs
123 07 06 05

当然,你可以只使用days=$((ts / 86400))天数,而不会受到一年价值的限制。

或者只是手动计算它们:

secs=$(( ts % 60)); 
mins=$(( ts / 60 % 60 )); 
hours=$(( ts / 3600 % 24));
days=$(( ts / 86400 ));

(这个eval技巧是从一些史蒂芬的答案,但我不记得是哪一个。)

相关内容