bash - 使用 macos ootb /bin/date 解析秒的意外输出
问题描述
minutes:seconds
使用 MacOS ootb以秒为单位格式化时间间隔/bin/date
可以使用以下格式按预期工作"+%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)
which 又指向strftime
which 说:
%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 秒的间隔,它表示 UTC 时间 1970 年 1 月 1 日午夜之后的 200 秒。所以如果我在我的 Mac 上运行它,我会得到:
$ date -j -f "%s" 200
Wed Dec 31 16:03:20 PST 1969
...因为我在美国太平洋时区。我目前处于太平洋夏令时间,但在 UTC 1970 年 1 月 1 日午夜后 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
但至少在我看来,这仍然只是一个 hack;根本问题是您将间隔与绝对时间混为一谈,我不相信这也不会导致其他问题。
推荐阅读
- java - 格式化参数的参数类型错误
- javascript - 计算待办事项应用程序Vue js中未完成的待办事项数量
- android - camera2 api -> mediaCodec -> mediaMuxer -> mp4 文件
- android - 如何通过 kotlin 的改造检查服务器是否可以访问?
- django-haystack - 错误:命令出错,退出状态为 1:python setup.py egg_info 检查日志以获取完整的命令输出。安装 django-haystack 时
- c++ - 如何在 C++ 中修剪原始设备地址区域?
- java - 使用堆外内存在 Java 中管理数组列表
- ios - 为什么xcode模拟器不显示全屏
- laravel - 对 "seen" 匹配 2 的结果进行排序
- bash - 为什么是美元?创建一个文件?