Bash macos ootb/bin/date的意外输出解析秒数

Bash macos ootb/bin/date的意外输出解析秒数,bash,macos,shell,date,strftime,Bash,Macos,Shell,Date,Strftime,使用MacOS ootb/bin/date将时间间隔(以秒为单位)格式化为minutes:seconds,使用“+%M:%S”格式可按预期工作: #将200秒转换为03:20 日期-j-f“%s”200+%M:%s #输出:03:20 #将3595秒转换为59:55秒 日期-j-f“%s”3595+%M:%s #产出:59:55 但是,当解析的值超过一小时(3600多秒)时,格式字符串“+%H:%M:%S”(以及等效的“+%T”)出现一个关闭错误: date-j-f“%s”3600++%H:%

使用MacOS ootb
/bin/date
将时间间隔(以秒为单位)格式化为
minutes:seconds
,使用
“+%M:%S”
格式可按预期工作:

#将200秒转换为03:20
日期-j-f“%s”200+%M:%s
#输出:03:20
#将3595秒转换为59:55秒
日期-j-f“%s”3595+%M:%s
#产出:59:55
但是,当解析的值超过一小时(3600多秒)时,格式字符串
“+%H:%M:%S”
(以及等效的
“+%T”
)出现一个关闭错误:

date-j-f“%s”3600++%H:%M:%s
#实际输出:02:00:00
#预期输出:01:00:00
的手册页提到
解析是使用strtime(3)
完成的,而strtime(3)
又指向以下内容:

%s替换为自纪元UTC起的秒数(请参阅mktime(3))。

根据以上内容,我希望3600被解析并格式化为
01:00:00
,而不是
02:00:00


我传递的参数是否有问题,或者这是一个实现错误?

基本问题是
date
不处理时间间隔,它处理绝对时间+日期。当您使用日期-j-f“%s”200时,它不会将“200”解释为200秒的间隔,而是指1970年1月1日UTC午夜后的200秒。如果我在Mac电脑上运行它,我会得到:

$ date -j -f "%s" 200
Wed Dec 31 16:03:20 PST 1969
…因为我在美国太平洋时区。我目前使用太平洋昼间时间,但在1970年1月1日UTC午夜后200秒,该区域将使用太平洋标准时间,因此它使用该时间显示时间和日期

你看到的基本上是一样的,但是由于你所在的区域比UTC早一个小时(或者是1970年1月1日),你得到的是一个小时的加减,而不是8减。除非显示小时数,否则不会注意到这一点,但即使时间“间隔”小于3600,也会发生:

$ date -j -f "%s" 200 "+%H:%M:%S"
16:03:20
(在您的时区中,您可能会看到“01:03:20”。)在非小时偏移的时区中,您可能会得到更奇怪的结果:

$ TZ=Canada/Newfoundland date -j -f "%s" 200  "+%H:%M:%S"
20:33:20
您可以通过告诉
date
以UTC格式输出,或者使用
-u
或者
TZ=UTC
来解决这个问题:

$ date -ju -f "%s" 3600  "+%H:%M:%S"
01:00:00
$ TZ=UTC date -j -f "%s" 3600  "+%H:%M:%S"
01:00:00

但至少在我看来,这仍然只是一个黑客;根本的问题是你把时间间隔和绝对时间混在一起了,我不相信这不会引起其他问题。

日期-j-f“%s”3595”+%H:%m:%s%Z%Z“的输出是什么?你在哪个时区?您的
语言环境是什么?您所在地区是否有夏令时?@KamilCuk:输出为
01:59:55 CET+0100
,与Gordon在接受的答案中解释的相符。语言环境设置为
LC\u ALL=“en\u US.UTF-8”
LANG=“en\u US.UTF-8”
。感谢您提供如此详细和启发性的解释!事实上,我使用
date
做的事情比它的本意要多,而且我没有意识到时区的调整。非常感谢。顺便说一句,为了完整性:GNU
日期似乎总是使用UTC时区进行解析;等效的GNU date命令
date-u-d@3600
返回
1970年1月1日星期四01:00:00 UTC
(可通过
brew安装coreutils在mac上复制),因此
gdate-u-d@3600+%H:%M:%S“
将输出
01:00:00
“始终使用UTC时区进行解析”,确定这就是
date-u
的意思。如果不需要UTC,请不要使用
-u