파이썬에서 인식하지 못하는 날짜 시간 시간대를 인식시키는 방법
내가 해야하는 것
시간대를 인식하지 못하는 datetime 객체가 있는데 다른 시간대를 인식하는 datetime 객체와 비교할 수 있도록 시간대를 추가해야합니다. 이 하나의 레거시 사례에 대해 전체 응용 프로그램을 표준 시간대로 변환하고 싶지 않습니다.
내가 시도한 것
먼저, 문제를 보여주기 위해 :
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> import pytz
>>> unaware = datetime.datetime(2011,8,15,8,15,12,0)
>>> unaware
datetime.datetime(2011, 8, 15, 8, 15, 12)
>>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC)
>>> aware
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> aware == unaware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
먼저 시간대로 시도했습니다.
>>> unaware.astimezone(pytz.UTC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: astimezone() cannot be applied to a naive datetime
>>>
실제로 변환을 시도하고 있기 때문에 이것이 실패한 것은 놀라운 일이 아닙니다. 바꾸기는 더 나은 선택처럼 보였습니다 ( Python에 따르면 : "timezone aware"인 datetime.today () 값을 얻는 방법은 무엇입니까? ) :
>>> unaware.replace(tzinfo=pytz.UTC)
datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>)
>>> unaware == aware
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't compare offset-naive and offset-aware datetimes
>>>
그러나 보시다시피 replace는 tzinfo를 설정하는 것으로 보이지만 객체를 인식하지 못합니다. 입력 문자열을 구문 분석하기 전에 시간대를 갖도록 닥터 링으로 넘어갈 준비가되어 있습니다 (필요한 경우 구문 분석을 위해 dateutil을 사용하고 있습니다).
또한 파이썬 2.6과 파이썬 2.7 에서이 결과를 시도했습니다.
문맥
일부 데이터 파일에 대한 파서를 작성 중입니다. 날짜 문자열에 시간대 표시 기가없는 곳에서 지원 해야하는 오래된 형식이 있습니다. 이미 데이터 소스를 수정했지만 여전히 레거시 데이터 형식을 지원해야합니다. 레거시 데이터의 일회성 변환은 다양한 비즈니스 BS 이유로 인해 옵션이 아닙니다. 일반적으로 기본 시간대를 하드 코딩하는 아이디어는 마음에 들지 않지만이 경우 가장 좋은 옵션 인 것 같습니다. 문제가되는 모든 레거시 데이터가 UTC로되어 있다는 확신을 가지고 있으며,이 경우 기본 설정의 위험을 감수 할 준비가되어 있습니다.
일반적으로 순진한 날짜 시간 시간대를 인식하려면 localize 메소드를 사용하십시오 .
import datetime
import pytz
unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC)
now_aware = pytz.utc.localize(unaware)
assert aware == now_aware
UTC 시간대의 경우 localize
처리 할 일광 절약 시간제 계산 이 없으므로 실제로 사용할 필요 는 없습니다.
now_aware = unaware.replace(tzinfo=pytz.UTC)
공장. ( .replace
새 날짜 시간을 반환하지만 수정하지 않습니다 unaware
.)
이 모든 예제는 외부 모듈을 사용하지만 이 SO 답변에 제시 된 것처럼 datetime 모듈 만 사용하여 동일한 결과를 얻을 수 있습니다 .
from datetime import datetime
from datetime import timezone
dt = datetime.now()
dt.replace(tzinfo=timezone.utc)
print(dt.replace(tzinfo=timezone.utc).isoformat())
'2017-01-12T22:11:31+00:00'
의존성이 적고 pytz 문제가 없습니다.
참고 : 이것을 python3 및 python2와 함께 사용하려면 시간대 가져 오기 (UTC 용 하드 코드)에도 사용할 수 있습니다.
try:
from datetime import timezone
utc = timezone.utc
except ImportError:
#Hi there python2 user
class UTC(tzinfo):
def utcoffset(self, dt):
return timedelta(0)
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return timedelta(0)
utc = UTC()
dt_aware에서 dt_unaware로 사용했습니다.
dt_unaware = dt_aware.replace(tzinfo=None)
dt_unware에서 dt_aware로
from pytz import timezone
localtz = timezone('Europe/Lisbon')
dt_aware = localtz.localize(dt_unware)
그러나 전에 대답하는 것도 좋은 해결책입니다.
Django 에서이 문장을 사용하여 인식하지 못하는 시간을 인식으로 변환합니다.
from django.utils import timezone
dt_aware = timezone.make_aware(dt_unaware, timezone.get_current_timezone())
이전 답변에 동의하며 UTC로 시작해도 괜찮습니다. 그러나 UTC가 아닌 현지 시간대 가있는 날짜 시간을 가진 tz 인식 값으로 작업하는 것이 일반적인 시나리오라고 생각합니다 .
그냥 이름 만 사용한다면 replace ()가 적용되고 올바른 날짜 / 시간 인식 객체가 생성 될 수 있습니다. 그렇지 않다.
replace (tzinfo = ...)는 동작이 무작위 인 것 같습니다 . 따라서 쓸모가 없습니다. 이것을 사용하지 마십시오!
localize는 올바른 기능입니다. 예:
localdatetime_aware = tz.localize(datetime_nonaware)
또는 더 완전한 예 :
import pytz
from datetime import datetime
pytz.timezone('Australia/Melbourne').localize(datetime.now())
현재 현지 시간의 시간대를 인식하는 시간대를 제공합니다.
datetime.datetime(2017, 11, 3, 7, 44, 51, 908574, tzinfo=<DstTzInfo 'Australia/Melbourne' AEDT+11:00:00 DST>)
이것은 @ Sérgio와 @unutbu의 답변을 체계화 합니다 . pytz.timezone
객체 또는 IANA 시간대 문자열 과 함께 "작동" 합니다.
def make_tz_aware(dt, tz='UTC', is_dst=None):
"""Add timezone information to a datetime object, only if it is naive."""
tz = dt.tzinfo or tz
try:
tz = pytz.timezone(tz)
except AttributeError:
pass
return tz.localize(dt, is_dst=is_dst)
이것은 어떤 것 같아 datetime.localize()
(또는 .inform()
또는 .awarify()
어떤 시간대가 지정되지 않은 경우 수행 UTC에 TZ 인수 및 기본 모두 문자열과 시간대 객체를 받아 들여야한다).
현지 시간대를 추가하기 위해; (dateutil 사용)
from dateutil import tz
import datetime
dt_unaware = datetime.datetime(2017, 6, 24, 12, 24, 36)
dt_aware = dt_unaware.replace(tzinfo=tz.tzlocal())
내가 아는 두 가지 방법
from datetime import datetime
import pytz
naive = datetime.now()
aware = naive.replace(tzinfo=pytz.UTC)
또는
aware = pytz.UTC.localize(naive)
물론 UTC 대신 모든 시간대를 사용할 수 있습니다.
unutbu의 답변 형식으로; 더 직관적 인 구문으로 이와 같은 것을 처리하는 유틸리티 모듈을 만들었습니다. 핍과 함께 설치할 수 있습니다.
import datetime
import saturn
unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0)
now_aware = saturn.fix_naive(unaware)
now_aware_madrid = saturn.fix_naive(unaware, 'Europe/Madrid')
참고 URL : https://stackoverflow.com/questions/7065164/how-to-make-an-unaware-datetime-timezone-aware-in-python
도와주세요.
'development' 카테고리의 다른 글
C #에서 다차원 배열과 배열 배열의 차이점은 무엇입니까? (0) | 2020.02.18 |
---|---|
파이썬 객체를 올바르게 정리하려면 어떻게합니까? (0) | 2020.02.18 |
collections.defaultdict는 어떻게 작동합니까? (0) | 2020.02.18 |
우분투에서 ssh-add로 개인 키를 영구적으로 추가하는 방법은 무엇입니까? (0) | 2020.02.18 |
여러 인수에 대한 Python 다중 처리 pool.map (0) | 2020.02.18 |