datetime.datetime.utcnow ()에 시간대 정보가없는 이유는 무엇입니까?


285
datetime.datetime.utcnow()

datetime명시 적으로 UTC라는 시간대 정보가없는 이유는 무엇 datetime입니까?

나는 이것을 포함 할 것으로 기대한다 tzinfo.


string 형식의 일반 iso 형식 날짜 필드를 utc 형식으로 변환하는 방법은 무엇입니까?
Navi

답변:


192

즉, 시간대가 순진하므로 사용할 수 없습니다. datetime.astimezone

이와 같은 시간대를 지정할 수 있습니다

import pytz  # 3rd party: $ pip install pytz

u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset

이제 시간대를 변경할 수 있습니다

print(u.astimezone(pytz.timezone("America/New_York")))

주어진 시간대에서 현재 시간을 얻으려면 tzinfo를 datetime.now()직접 전달할 수 있습니다.

#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz

print(datetime.now(pytz.timezone("America/New_York")))

일광 절약 시간 (DST)을 준수하는 시간대를 포함하여 모든 시간대에서 작동합니다. 즉, 다른 시간에 다른 utc 오프셋을 가질 수있는 시간대 (고정되지 않은 utc 오프셋)에서 작동합니다. 사용하지 마십시오 tz.localize(datetime.now()). 현지 시간이 모호한 경우 DST 종료 전이 중에 실패 할 수 있습니다.


216
그러나 시간대가 순진한 이유는 없습니다. UTC로 지정되어 있습니다. 제대로 작동하도록 타사 라이브러리를 검색해야하는 이유는 무엇입니까?
Mark Ransom

4
나는 동의한다; 나를 위해 '순진한'시간은 완전히 쓸모가 없습니다. 현재 파이썬 목록에 대해 stdlib에 pytz를 추가하는 것에 대한 토론이 있습니다. 문제는 라이센스가 아니라 시간대 데이터가 너무 자주 업데이트된다는 사실입니다 (파이썬 자체는 불가능합니다). 또한 pytz는 예상 방식으로 tzinfo 인터페이스를 구현하지 않으므로에서 일부 도시 시간대를 사용하려고하면 오류가 발생할 수 있습니다 astimezone. 따라서 datetime에는 기본 시간대가 없을뿐만 아니라 널리 사용 가능한 tzinfo 구현은 가정 된 표준을 준수하지 않습니다.
bobince

5
@bobince 왜 pytz와 표준 날짜 / 시간 라이브러리가 작동하지 않습니까? 독립적 인 프로젝트로 발전하는 Python 코어와 pytz는 코어 팀의 물류 복잡성을 줄입니다. 예, Python 핵심 팀의 복잡성을 줄이면 시간대를 처리 해야하는 모든 Python 사용자의 복잡성이 증가하지만 정당한 이유로이 결정을 내렸다고 믿습니다. "표준 라이브러리에 tzinfo 인스턴스가 없습니다 ..."규칙은 간단하기 때문에 훌륭합니다. 왜 여기서 예외를 만들까요?
Derek Litz

15
어때요u=datetime.now(pytz.utc)
Craig McQueen

4
@bain : 사용하지 마십시오 tz.localize(datetime.now()); 사용하는 datetime.now(tz)대신.
jfs

142

Python 3.2 이후에는 datetime모듈에가 포함되어 있습니다 datetime.timezone. 에 대한 설명서 datetime.utcnow()는 다음과 같습니다.

을 호출하여 현재 UTC 날짜 시간을 알 수 있습니다 .datetime.now(timezone.utc)

그래서 당신은 할 수 있습니다 :

>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)

2
어느 것이 선호됩니까? datetime.now(timezone.utc)또는 datetime.utcnow(timezone.utc)?
Jesse Webb

8
datetime.utcnow()논쟁이 없다. 따라서이어야 datetime.now(timezone.utc)합니다.
Craig McQueen

1
datetime.now()기계 시간 datetime.utcnow()을 반환 하지만 실제 UTC 시간을 반환합니다.
Babu

13
@Babu : UTC임을 나타내도록 datetime.utcnow()설정되지 않았습니다 tzinfo. 그러나 설정된 datetime.now(datetime.timezone.utc)UTC 시간 반환 tzinfo합니다.
Craig McQueen 2016 년

@CraigMcQueen 그래서 tz지금 생성자에서 객체를 전달하면 해당 시간대의 시간을 반환합니까? 확인! 지적 해 주셔서 감사합니다.
Babu

71

표준 파이썬 라이브러리에는 tzinfo 클래스가 포함되어 있지 않습니다 (그러나 pep 431 참조) ). 이유 만 추측 할 수 있습니다. 개인적으로 UTC에 tzinfo 클래스를 포함시키지 않는 것은 실수라고 생각합니다. 표준 구현을 가질만큼 논란의 여지가 없기 때문입니다.

편집 : 라이브러리에는 구현이 없지만 tzinfodocumentation에 예제가 있습니다 .

from datetime import timedelta, tzinfo

ZERO = timedelta(0)

# A UTC class.

class UTC(tzinfo):
    """UTC"""

    def utcoffset(self, dt):
        return ZERO

    def tzname(self, dt):
        return "UTC"

    def dst(self, dt):
        return ZERO

utc = UTC()

이를 사용하려면 현재 시간을 인식 가능한 datetime 객체로 가져 오십시오.

from datetime import datetime 

now = datetime.now(utc)

datetime.timezone.utcPython 3.2 이상 에는 다음이 있습니다 .

from datetime import datetime, timezone 

now = datetime.now(timezone.utc)

8
왜이 클래스가 처음에 제공되지 않았는지 (그리고 더 중요하게는에서 datetime만든 객체에 사용 된 utcnow()) 이유를 알아보십시오 ...
André Caron

17
시간대 객체 timezone.utc가 마침내 Python 3.2에 추가되었습니다. 이전 버전과의 호환성을 utcnow()위해 표준 시간대없는 시간 개체를 반환하지만을 호출하여 원하는 것을 얻을 수 있습니다 now(timezone.utc).
mhsmith 2016 년

4
@rgove, 그것은 파이썬 3에서 공정한 게임으로 여겨 졌던 잘못에 대한 권리의 종류입니다. 그들은 하위 호환성에 대해 걱정할 필요가 없었습니다. 지난 몇 일 동안 읽은 또 다른 예가 있습니다. struct모듈은 유니 코드에서 바이트 문자열로 자동 변환을 수행하며 최종 결정은 잘못된 결정이 진행되는 것을 방지하기 위해 이전 Python 3 버전과의 호환성을 중단하는 것입니다.
Mark Ransom 2016 년

2
파이썬의 tzinfo문서에는 그것을 구현하는 코드의 예가 포함되어 있지만, 날짜 시간 자체에는 해당 기능이 포함되어 있지 않습니다. docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc
LS

1
@LS 예, pytz훌륭한 자료입니다. 예제 코드를 작성하기 위해 내 답변을 편집 할 때 누군가 다른 사람이 이미 제안했으며 천둥을 훔치고 싶지 않았습니다.
Mark Ransom

20

pytz모듈은 하나 개의 옵션이며, 또 다른이python-dateutil 있지만 타사 패키지는, 또한 이미 다른 종속성 및 운영 체제에 따라 사용할 수있다.

방금이 방법론을 참조 용으로 포함하고 싶었습니다. 이미 python-dateutil다른 목적으로 설치 한 경우 tzinfo에는 복제 하는 대신 사용할 수 있습니다pytz

import datetime
import dateutil.tz

# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())

# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())

# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())

전화를 utcnow하려면 UTC 시간대 정보가 포함되어야 한다는 데 동의합니다 . 기본 날짜 시간 라이브러리는 기본적으로 상호 호환성을 위해 순진 날짜 시간으로 설정되므로 이것이 포함되지 않은 것 같습니다.


1
NameError : 이름 'dt'가 정의되지 않았습니다
xApple

datetime.datetime.utcfromtimestamp () 호출을 사용하고 tzinfo를 추가해야했습니다. 두 번째 해결책은 저에게 효과적이었습니다. utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
Ian Lee

1
참고 : 달리 datetime.now(pytz_tz)항상 작동합니다. datetime.now(dateutil.tz.tzlocal())DST 전환 중에 실패 할 수 있습니다 . PEP 495-현지 시간 모호함dateutil향후 상황을 개선 할 수 있습니다.
jfs

@IanLee : 당신은 사용할 수 있습니다 utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())(: 메모를 dateutil상쇄 비 고정 UTC (예와 함께 dateutil.tz.tzlocal()여기에 실패 할 수 있습니다) 사용 대신 기반 솔루션 ). pytz
jfs

내 프로그램이 이미 수입 된 이후 dateutil에 대해 dateutil.parser, 나는 최선이 솔루션을 좋아했다. 다음과 같이 간단했습니다 utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc()). 비올라!!
LS

11

Julien Danjou는 왜 시간대를 다루지 말아야하는지 설명하는 좋은 기사를 썼습니다 . 발췌 :

실제로 Python datetime API는 항상 알지 못하는 datetime 객체를 반환하므로 매우 불행합니다. 실제로이 개체 중 하나를 가져 오면 표준 시간대를 알 수있는 방법이 없으므로 이러한 개체는 자체적으로 "무용지물"입니다.

아아, 당신이 사용할 수는 있지만 utcnow(), 발견 한대로 시간대 정보는 여전히 표시되지 않습니다.

추천 :

  • 항상 datetime시간대 정보와 같은 인식 객체를 사용 하십시오. 이를 통해 직접 비교할 수 있으며 (인식 및 인식 datetime 되지 않는 객체는 비교할 수 없음) 사용자에게 올바르게 반환합니다. pytz 를 활용 하여 표준 시간대 개체를 갖습니다.

  • 입력 및 출력 문자열 형식으로 ISO 8601 을 사용하십시오 . 사용 datetime.datetime.isoformat()문자열로 반환 타임 스탬프로는 시간대 정보를 포함하는 형식을 사용하여 포맷.

  • ISO 8601 형식의 타임 스탬프가 포함 된 문자열을 구문 분석해야하는 경우을 사용 iso8601하여 올바른 시간대 정보가있는 타임 스탬프를 반환 할 수 있습니다 . 타임 스탬프를 직접 비교할 수 있습니다.


1
이것은 약간 잘못된 제안입니다. 경험상 시간대는 절대 다루지 않습니다. 항상 tz unware utc 오브젝트 (에포크 오브젝트)를 저장하고 전송하십시오. 시간대는 UI에서 표현할 때만 계산되어야합니다
nehem

1
그것은 이미 Julien의 생각과 잘 어울리는 것 같습니다. (위에서 언급 한) 그의 특정 권고 중 어떤 것이 오해의 소지가 있습니까?
Joe D' Andrea

10

timezonePython 3.2 이상에서 정보 를 추가하려면

import datetime

>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'

1
AttributeError: 'module' object has no attribute 'timezone' 파이썬 2.7.13 (기본값 월 (19) 2017 14시 48분 8초)
마르신 Owsiany

-6
from datetime import datetime 
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]

-13

UTC 날짜는 UTC이므로 시간대 정보가 필요하지 않습니다. 정의에 따르면 오프셋이 없습니다.


10
docs.python.org/library/datetime.html 에서 알 수 있듯이 tzinfo가없는 날짜 시간은 시간대를 지정하지 않은 시간입니다. 여기에 시간대 지정되었으므로 논리적으로 존재해야합니다. 연결된 표준 시간대가없는 날짜 / 시간과 UTC 형식의 날짜 / 시간 간에는 큰 차이가 있습니다. (이상적으로 ... 그들은 IMO 다른 유형해야하지만, 그것은 또 다른 문제이다)
존 소총

@JonSkeet UTC가 시간대가 아니라는 Ignacio의 요점을 놓치고 있다고 생각합니다. 내가 이것을 입력 할 때이 답변의 점수가 -9 인 것에 대해 놀랍습니다 ...
CS

3
@CS : 음 이그나시오는 엄밀히 말하면 UTC는 시간대 아니지만 ... 그리고, 보통 있다고 언급 결코 처리 상당히 간단합니다 (예 :와, 파이썬을 포함하여 삶을 만들기 위해 하나 pytz.utc). UTC로부터의 오프셋을 알 수없는 값과 0으로 알려진 값 사이에는 큰 차이가 있습니다. 후자는 IMO를 반환 utcnow() 해야합니다 . 이는 문서에 따라 "인식 대상은 해석에 개방되지 않은 특정 시점을 나타내는 데 사용됩니다"와 일치합니다.
Jon Skeet
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.