使用 macos ootb /bin/date 的意外输出解析秒数
Unexpected output parsing seconds with macos ootb /bin/date
使用 MacOS ootb /bin/date
将以秒为单位的时间间隔格式化为 minutes:seconds
使用 "+%M:%S"
格式可按预期工作:
# convert 200 seconds to 03:20
date -j -f "%s" 200 "+%M:%S"
# OUTPUT: 03:20
# convert 3595 seconds to 59:55
date -j -f "%s" 3595 "+%M:%S"
# OUTPUT: 59:55
然而,当解析值超过一小时(3600+ 秒)时,格式字符串 "+%H:%M:%S"
(以及等效的 "+%T"
)似乎有一个差一错误:
date -j -f "%s" 3600 "+%H:%M:%S"
# ACTUAL OUTPUT: 02:00:00
# EXPECTED OUTPUT: 01:00:00
date
的联机帮助页提到 Parsing is done using strptime(3)
又指向 strftime
其中说:
%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3)).
根据上述我希望 3600 被解析和格式化为 01:00:00
而不是 02:00:00
.
我传递的参数有问题还是这是一个实现错误?
基本问题是 date
不处理时间间隔,它处理绝对时间+日期。当您使用 date -j -f "%s" 200
时,它不会将“200”解释为 200 秒的间隔,它表示 1970 年 1 月 1 日午夜后 200 秒,UTC。所以如果我 运行 在我的 Mac 上,我得到这个:
$ date -j -f "%s" 200
Wed Dec 31 16:03:20 PST 1969
...因为我在美国太平洋时区。我目前使用的是太平洋夏令时,但是在 1970 年 1 月 1 日午夜后 200 秒,UTC,这个区域本来是太平洋 标准 时间,所以它使用它来显示时间和日期。
你看到的基本上是一样的,但由于你所在的地区比 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
但至少在我看来,这仍然只是一个 hack;根本问题是您混淆了时间间隔和绝对时间,我不相信这不会导致其他问题。
使用 MacOS ootb /bin/date
将以秒为单位的时间间隔格式化为 minutes:seconds
使用 "+%M:%S"
格式可按预期工作:
# convert 200 seconds to 03:20
date -j -f "%s" 200 "+%M:%S"
# OUTPUT: 03:20
# convert 3595 seconds to 59:55
date -j -f "%s" 3595 "+%M:%S"
# OUTPUT: 59:55
然而,当解析值超过一小时(3600+ 秒)时,格式字符串 "+%H:%M:%S"
(以及等效的 "+%T"
)似乎有一个差一错误:
date -j -f "%s" 3600 "+%H:%M:%S"
# ACTUAL OUTPUT: 02:00:00
# EXPECTED OUTPUT: 01:00:00
date
的联机帮助页提到 Parsing is done using strptime(3)
又指向 strftime
其中说:
%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3)).
根据上述我希望 3600 被解析和格式化为 01:00:00
而不是 02:00:00
.
我传递的参数有问题还是这是一个实现错误?
基本问题是 date
不处理时间间隔,它处理绝对时间+日期。当您使用 date -j -f "%s" 200
时,它不会将“200”解释为 200 秒的间隔,它表示 1970 年 1 月 1 日午夜后 200 秒,UTC。所以如果我 运行 在我的 Mac 上,我得到这个:
$ date -j -f "%s" 200
Wed Dec 31 16:03:20 PST 1969
...因为我在美国太平洋时区。我目前使用的是太平洋夏令时,但是在 1970 年 1 月 1 日午夜后 200 秒,UTC,这个区域本来是太平洋 标准 时间,所以它使用它来显示时间和日期。
你看到的基本上是一样的,但由于你所在的地区比 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
但至少在我看来,这仍然只是一个 hack;根本问题是您混淆了时间间隔和绝对时间,我不相信这不会导致其他问题。