为什么Python的日期时间ISO函数逻辑上不正确和错误?

vy3*_*y32 3 python iso8601

我有点惊讶的是python datetime .isoformat()函数没有返回正确的信息.当为fromtimestamp()方法提供时区时,该函数正确返回ISO 8601格式的字符串.但是,在计算结果时会忽略时区.注意:

13:29 msimsonnet:~$ python
Python 2.7.1 (r271:86832, Jan 26 2011, 13:56:46) 
[GCC 4.2.1 (Apple Inc. build 5664)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
Running with pythonstartup.py
>>> import pytz,datetime
>>> datetime.datetime.fromtimestamp(1303876413).isoformat()
'2011-04-26T23:53:33'
>>> ny = pytz.timezone('America/New_York')
>>> sf = pytz.timezone('America/Los_Angeles')
>>> datetime.datetime.fromtimestamp(1303876413,ny).isoformat()
'2011-04-26T23:53:33-04:00'
>>> datetime.datetime.fromtimestamp(1303876413,sf).isoformat()
'2011-04-26T20:53:33-07:00'
>>> 
Run Code Online (Sandbox Code Playgroud)

我是在EDT的计算机上运行的(格林威治标准时间-400).时间1303876413实际上是2011年4月26日晚上11:53:33,那时我第一次写了这个问题.请注意,在第一个示例中,只是请求.isoformat()返回'2011-04-26T23:53:33',这是错误的 - 它应该返回'2011-04-26T23:53:33-04:00',因为它返回本地时间并且Python知道时区.第二个例子是正确的,但我在纽约时区对象中干扰.第三个例子是错误的--Python正在保留时区,但它没有相应地调整时间.

附录:

如果您阅读了所有评论,您将看到我正在寻找的行为可以使用utcfromtimestamp而不是fromtimestamp

TM.*_*TM. 17

确保使用"时区感知" datetime对象,而不是"天真"对象.

为了使时区"识别" datetime对象,您需要确保在创建时区时提供时区.

更多细节请访问:http: //docs.python.org/library/datetime.html

此外,ISO 8601并没有要求时区,并isoformat 标准.实际上,它根本不支持时区,只支持UTC的时间偏移.

ISO 8601允许许多不同的格式,例如,这些格式都是有效的:

2011-04-27
2011-04-27 02:48Z
2011-04-27T02:48Z
2011-W17-3
2011-117
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参见http://en.wikipedia.org/wiki/ISO_8601.

编辑,以解决您的更新:

它没有错误,它运行正常,并根据文档.天真的日期时间对象只是没有任何时区信息,句号.所以没有理由期望他们在你打电话时能给你时区信息isoformat().

使用时间戳创建对象时,它会根据python认为您的系统时区是什么来生成本地时间datetime对象.这就是为什么当你给它一个posix时间戳时,它会把它转换成你当地的时间.请注意,虽然datetime模块知道时间戳是UTC,并且它知道您的本地时区,并fromtimestamp使用该信息来创建日期时间对象,但结果对象仍然是天真的,并且与时区无关.如果要使用时间戳,则不应使用天真的日期时间对象.

来自文档:

天真的日期时间对象是否代表协调世界时(UTC),当地时间或某个其他时区的时间完全取决于程序,就像程序一样,特定数字是代表米,英里还是质量.天真的日期时间对象易于理解和使用,代价是忽略了现实的某些方面.

以下是该fromtimestamp方法的文档(添加了粗体):

返回与POSIX时间戳对应的本地日期和时间,例如time.time()返回的日期和时间.如果可选参数tz为None或未指定,则时间戳将转换为平台的本地日期和时间,并且返回的datetime对象是天真的.

如果你想让它考虑时区,你需要通过一个时区,它不会为你推断它. 仅仅因为它没有做你认为它应该做的事情并不会使它不合规或有缺陷.它按预期工作,并且记录在案.这几乎与越野车相反.