OSX 无法将 ISO8601 转换为纪元

OSX fails to convert ISO8601 to epoch

我在 mac os 上安顿下来,我的一些脚本在 linux 后无法运行。特别是一个脚本非常有趣。

所以我正在尝试将 ISO8601 日期转换为 unix 纪元。 OSX 原生方式似乎是

$ date -j -f "%FT%TZ" "2015-09-09T13:19:09Z"
Wed  9 Sep 2015 13:19:09 NZST

$ date -j -f "%FT%TZ" "2015-09-09T13:19:09Z"  +%s
1441761549

看起来不错,只是答案有误。它比实际答案和我的时区 +12 晚了整整 12 小时,那么云时区如何影响 unix 纪元?

并且只是验证我自己

$ docker run -it --rm trusty date -d"2015-09-09T13:19:09Z" +%s
1441804749

linux 上的相同工具给出正确答案...

我只想了解这里出了什么问题 - 我是漏掉了什么还是只是坏掉了?

OSX Yosemite 10.10.4

更新: 只是一些额外的细节 - 我建议它是 date util 之间的区别,除了它不仅是 date.

Stass-MacBook:~ void$ python -c 'import dateutil.parser; print dateutil.parser.parse("2015-09-09T13:19:09Z").strftime("%s")'
1441761549

Stass-MacBook:~ void$ docker run trusty python -c 'import dateutil.parser; print dateutil.parser.parse("2015-09-09T13:19:09Z").strftime("%s")'
1441804749

简短的回答是,当您使用这些参数 运行 macOS/BSD date 实用程序时,您得到的输出是预期的正确输出。因为它不同于 GNU date.

要从 GNU date 获得类似的输出,您需要添加 --utc 选项,运行 就像这样:

echo $(date --utc -d '2015-09-09T13:19:09Z' +"%a %-d %b %Y %H:%M:%S") $(date +%Z)

如果您的时区设置为 NZST,那么上面的代码将发出:

Wed 9 Sep 2015 13:19:09 NZST

当 运行 为 date -j -f "%FT%TZ" "2015-09-09T13:19:09Z" 时,您可以想象 BSD date 所做的调用。一方面,即使您说的是将此 date/time 放入默认格式(并且不要更改它),它也会在那里扔一个时区。

另一种思考它在做什么的方法是:默认情况下,BSD date 的运行就好像你已经给出了 --utc 选项的等价物一样——也就是说,基本上与GNU date 默认值。

换句话说,与 BSD date -j -f 的一个重要区别是它实际上只是意味着:将此字符串采用其他日期格式并将其放入我们使用的默认日期格式在这里使用——完全不考虑本地时区.

same tools on linux giving correct answer ...

macOS/BSD date 和 GNU/Linux date 不是同一种工具。他们只是有相同的名字。


至于让脚本中的 date 跨平台表现相同,您可以通过使用自制软件安装 coreutils 包来获得 GNU date

brew install coreutils

这将使 GNU 版本在您的 OS X 系统上可用,名称为 gdate。因此,您可以将脚本中的 date 替换为 $DATECMD (或其他内容),然后:

  • 在您的 OS X 环境中,set DATECMD=gdate
  • 在您的 Linux 环境中,set DATECMD=date

当然你也可以只做 alias date=gdate 不推荐 ,因为你有时可能想要 运行 确实期望的第 3 方工具BSD date 在您的环境中。