我正在传递一个时间间隔(以秒为单位)ts
。
ts=13
printf -v hours '%(%H)T' "$ts"
printf '%s\n' "ts: $ts ; hours: $hours"
这是不正确的结果。
时间:13;小时:12
正如您所看到的,我得到的12
不是00
13 秒。
答案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
技巧是从一些史蒂芬的答案,但我不记得是哪一个。)