Python UTC datetime 객체의 ISO 형식에는 Z (Zulu 또는 Zero 오프셋)가 포함되지 않습니다.


120

Python 2.7이 JavaScript와 달리 UTC datetime 객체의 isoformat 문자열 끝에 Z 문자 (Zulu 또는 0 오프셋)를 포함하지 않는 이유는 무엇입니까?

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

반면 자바 스크립트

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

1
Python datetime 값에는 시간대 정보가 없습니다. 타임 스탬프에 시간대 정보를 저장하려면 pytz 또는 Babel을 사용해보십시오.
tnknepp 2013

67
datetime.datetime.utcnow().isoformat() + 'Z'
jfs


3
.. 그리고 누락 된 Z는 놀랍게도 API 호출과 같은 일부 작동하지 않는 원인이됩니다
cardamom

더 나빠집니다. datetime의 마지막 부분이 0이면 잘립니다 ...
ntg

답변:


52

Python datetime객체에는 기본적으로 시간대 정보가 없으며,없는 경우 Python은 실제로 ISO 8601 사양을 위반합니다 ( 시간대 정보가 제공되지 않으면 현지 시간으로 간주 됨 ). pytz 패키지 를 사용하여 기본 시간대를 가져 오거나 직접 하위 클래스를 만들 수 있습니다 tzinfo.

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

그런 다음 수동으로 시간대 정보를 utcnow()다음에 추가 할 수 있습니다 .

>>> datetime.utcnow().replace(tzinfo=simple_utc()).isoformat()
'2014-05-16T22:51:53.015001+00:00'

이것은 UTC의 접미사로 Z또는 둘 중 하나를 허용하는 ISO 8601 형식을 준수합니다 +00:00. 후자는 표준 시간대가 일반적으로 표시되는 방식으로 실제로 표준을 더 잘 준수합니다 (UTC는 특별한 경우).


108
Z대신 어떻게 포함 +00:00합니까?
leopoodle

14
경고!!! pytz파이썬의 tzinfo프로토콜을 위반 하고 사용하기 위험합니다! blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html
ivan_pozdeev

@ivan_pozdeev 매우 흥미로운 링크에 감사드립니다. dateutil작업을 허용하는 변경 사항 은 PEP 495가 포함 된 Python 3.6까지 구현 pytz되지 않았으므로 인터페이스가 변경 되었기 때문에 표준 인터페이스를 사용하지 않았다는 것은 불공평합니다. 변경 이전에 작동하게하는 유일한 방법은 작동 방식이었습니다 pytz.
Mark Ransom

67

선택권: isoformat()

Python 은 UTC에 대한 'Z'접미사와 같은 군사 시간대 접미사를 datetime지원하지 않습니다 . 다음과 같은 간단한 문자열 교체가 트릭을 수행합니다.

In [1]: import datetime

In [2]: d = datetime.datetime(2014, 12, 10, 12, 0, 0)

In [3]: str(d).replace('+00:00', 'Z')
Out[3]: '2014-12-10 12:00:00Z'

str(d) 본질적으로 다음과 같습니다. d.isoformat(sep=' ')

참조 : Datetime, Python 표준 라이브러리

선택권: strftime()

또는 strftime동일한 효과를 얻기 위해 사용할 수 있습니다 .

In [4]: d.strftime('%Y-%m-%d %H:%M:%SZ')
Out[4]: '2014-12-10 12:00:00Z'

참고 :이 옵션은 지정된 날짜가 UTC 인 경우에만 작동합니다.

참조 : datetime.strftime ()


추가 : 사람이 읽을 수있는 시간대

더 나아가 시간대 플래그 pytz와 함께 사람이 읽을 수있는 시간대 정보를 표시하는 데 관심이있을 수 있습니다 strftime %Z.

In [5]: import pytz

In [6]: d = datetime.datetime(2014, 12, 10, 12, 0, 0, tzinfo=pytz.utc)

In [7]: d
Out[7]: datetime.datetime(2014, 12, 10, 12, 0, tzinfo=<UTC>)

In [8]: d.strftime('%Y-%m-%d %H:%M:%S %Z')
Out[8]: '2014-12-10 12:00:00 UTC'

1
구분자 T는 공백 대신에 있어야하지 않습니까?
Marcello Romani

1
d = datetime.datetime(2014, 12, 10, 12, 0, 0, tzinfo=datetime.timezone.utc)2 행에 있어야합니다 . Btw., RFC3339 에서는 공백이 'T'대신 'ok'라고 말합니다.
MrFuppes

16

다음 javascript 및 python 스크립트는 동일한 출력을 제공합니다. 나는 그것이 당신이 찾고있는 것이라고 생각합니다.

자바 스크립트

new Date().toISOString()

파이썬

import datetime

datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z'

그들이 제공하는 출력은 3 밀리 초 유효 숫자가있는 ISO 문자열로 형식이 지정되고 Z가 추가 된 utc (zelda) 시간입니다.

2019-01-19T23:20:25.459Z

12

Python> = 3.2에서는 간단히 다음을 사용할 수 있습니다.

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

3
아주 좋은 솔루션입니다. 에 대한 질문의 Z경우 오프셋을 클립 할 수 있습니다..isoformat()[:-6] + 'Z'
Maximilian Burszley

11

파이썬 날짜 시간은 약간 어색합니다. 사용 arrow.

> str(arrow.utcnow())
'2014-05-17T01:18:47.944126+00:00'

Arrow는 본질적으로 datetime과 동일한 API를 가지고 있지만 시간대와 메인 라이브러리에 있어야하는 몇 가지 추가 기능이 있습니다.

Javascript와 호환되는 형식은 다음을 통해 얻을 수 있습니다.

arrow.utcnow().isoformat().replace("+00:00", "Z")
'2018-11-30T02:46:40.714281Z'

자바 스크립트 Date.parse는 타임 스탬프에서 마이크로 초를 조용히 떨어 뜨립니다.


7
문자열이 'Z'로 끝나지 않기 때문에 질문에 대답하지 않습니다.
kaleissin

3

게시물에 대한 좋은 답변이 많이 있지만 JavaScript에서와 마찬가지로 형식이 정확하게 나오기를 원했습니다. 이것은 내가 사용하고 있으며 잘 작동합니다.

In [1]: import datetime

In [1]: now = datetime.datetime.utcnow()

In [1]: now.strftime('%Y-%m-%dT%H:%M:%S') + now.strftime('.%f')[:4] + 'Z'
Out[3]: '2018-10-16T13:18:34.856Z'

3
pip install python-dateutil
>>> a = "2019-06-27T02:14:49.443814497Z"
>>> dateutil.parser.parse(a)
datetime.datetime(2019, 6, 27, 2, 14, 49, 443814, tzinfo=tzutc())

2

나는 몇 가지 목표를 가지고이 문제에 접근했다.

  • ISO 8601 형식으로 UTC "인식"datetime 문자열 생성
  • datetime 객체 및 문자열 생성을 위해 Python 표준 라이브러리 함수 사용
  • Django timezone유틸리티 함수를 사용하여 datetime 객체와 문자열의 유효성을 검사 하고dateutil 파서로
  • JavaScript 함수를 사용하여 ISO 8601 datetime 문자열이 UTC를 인식하는지 확인합니다.

이 접근 방식 Z 접미사를 포함 하지 않고를 사용 하지 않지만 Python 문서utcnow()권장 사항을 기반으로하며 Django 및 JavaScript와 함께 소집을 전달합니다.

다음 datetime.now()을 사용 하는 대신 UTC 시간대 객체를 전달하는 것으로 시작하겠습니다 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'

모습에 좋은, 그래서 보자 무엇 장고와 dateutil생각 :

from django.utils.timezone import is_aware

is_aware(datetime.now(timezone.utc))
>>> True

import dateutil.parser

is_aware(dateutil.parser.parse(datetime.now(timezone.utc).isoformat()))
>>> True

좋아요, 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

이 블로그 게시물 을 읽어 볼 수도 있습니다 .


1
기본 라이브러리 기능을 고수하고 이전 게시물에 대한 후속 조치에 대한 보너스.
Victor Romeo

1

위의 모든 답변을 결합하여 다음 기능을 제공했습니다.

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)

1

나는 진자를 사용합니다.

import pendulum


d = pendulum.now("UTC").to_iso8601_string()
print(d)

>>> 2019-10-30T00:11:21.818265Z

0
>>> import arrow

>>> now = arrow.utcnow().format('YYYY-MM-DDTHH:mm:ss.SSS')
>>> now
'2018-11-28T21:34:59.235'
>>> zulu = "{}Z".format(now)
>>> zulu
'2018-11-28T21:34:59.235Z'

또는 한꺼번에 얻을 수 있습니다.

>>> zulu = "{}Z".format(arrow.utcnow().format('YYYY-MM-DDTHH:mm:ss.SSS'))
>>> zulu
'2018-11-28T21:54:49.639Z'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.