为什么python 2.7不包括Z字符(Zulu或零偏移量)在UTC datetime对象的isoformat字符串结束不像JavaScript?

>>> datetime.datetime.utcnow().isoformat()
'2013-10-29T09:14:03.895210'

而在javascript中

>>>  console.log(new Date().toISOString()); 
2013-10-29T09:38:41.341Z

当前回答

通过结合以上所有答案,我得到了以下函数:

from datetime import datetime, tzinfo, timedelta
class simple_utc(tzinfo):
    def tzname(self,**kwargs):
        return "UTC"
    def utcoffset(self, dt):
        return timedelta(0)


def getdata(yy, mm, dd, h, m, s) :
    d = datetime(yy, mm, dd, h, m, s)
    d = d.replace(tzinfo=simple_utc()).isoformat()
    d = str(d).replace('+00:00', 'Z')
    return d


print getdata(2018, 02, 03, 15, 0, 14)

其他回答

只使用标准库,不假设时区已经是UTC,并返回问题中要求的确切格式:

dt.astimezone(timezone.utc).replace(tzinfo=None).isoformat(timespec='milliseconds') + 'Z'

不过,这确实需要Python 3.6或更高版本。

下面的javascript和python脚本给出相同的输出。我觉得这就是你想要的。

JavaScript

new Date().toISOString()

Python

from datetime import datetime

datetime.utcnow().isoformat()[:-3]+'Z'

它们给出的输出是格式化为ISO字符串的UTC (zulu)时间,其中有一个3毫秒的有效数字,并附加一个Z。

2019-01-19T23:20:25.459Z

在Python >= 3.2中,你可以简单地使用:

>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).isoformat()
'2019-03-14T07:55:36.979511+00:00'

您的目标不应该是添加一个Z字符,而是生成一个ISO 8601格式的UTC“感知”日期时间字符串。解决方案是将UTC时区对象传递给datetime.now(),而不是使用datetime.utcnow():

from datetime import datetime, timezone

datetime.now(timezone.utc)
>>> datetime.datetime(2020, 1, 8, 6, 6, 24, 260810, tzinfo=datetime.timezone.utc)

datetime.now(timezone.utc).isoformat()
>>> '2020-01-08T06:07:04.492045+00:00'

看起来不错,让我们看看Django和dateutil是怎么想的:

from django.utils.timezone import is_aware
is_aware(datetime.now(timezone.utc))
>>> True

from dateutil.parser import isoparse
is_aware(isoparse(datetime.now(timezone.utc).isoformat()))
>>> True

注意,您需要从dateutil使用isopparse()。因为datetime.fromisoformat()的Python文档说它“不支持解析任意ISO 8601字符串”。

好的,Python datetime对象和ISO 8601字符串都是UTC“感知”的。现在让我们看看JavaScript是如何看待datetime字符串的。从这个答案中我们可以得到:

let date = '2020-01-08T06:07:04.492045+00:00';
const dateParsed = new Date(Date.parse(date))

document.write(dateParsed);
document.write("\n");
// Tue Jan 07 2020 22:07:04 GMT-0800 (Pacific Standard Time)

document.write(dateParsed.toISOString());
document.write("\n");
// 2020-01-08T06:07:04.492Z

document.write(dateParsed.toUTCString());
document.write("\n");
// Wed, 08 Jan 2020 06:07:04 GMT

注:

我有几个目标来解决这个问题:

生成ISO 8601格式的UTC“感知”日期时间字符串 仅使用Python标准库函数创建datetime对象和字符串 使用Django的timezone实用函数、dateutil解析器和JavaScript函数验证datetime对象和字符串

注意,这种方法不包括Z后缀,也不使用utcnow()。但是它是基于Python文档中的建议,并且它在Django和JavaScript中都是合格的。

参见:

停止使用utcnow和utcfromtimestamp 什么是“正确的”JSON日期格式?

通过结合以上所有答案,我得到了以下函数:

from datetime import datetime, tzinfo, timedelta
class simple_utc(tzinfo):
    def tzname(self,**kwargs):
        return "UTC"
    def utcoffset(self, dt):
        return timedelta(0)


def getdata(yy, mm, dd, h, m, s) :
    d = datetime(yy, mm, dd, h, m, s)
    d = d.replace(tzinfo=simple_utc()).isoformat()
    d = str(d).replace('+00:00', 'Z')
    return d


print getdata(2018, 02, 03, 15, 0, 14)