python 3.6 이하 버전에서는 datetime을 생성하면 timezone 정보가 없어 astimezone 같은 메소드를 실행하면 에러가 발생합니다. 지금부터 삽질해서 찾은 방법을 설명합니다. 


python 3.6은 datetime을 생성할 때 timezone을 지정하지 않아도 기본으로 내장으로 설정이 되어 있어 astimezone()를 실행해도 에러가 발생하지 않습니다. 하지만 3.6이하 버전은 datetime을 생성할 때 timezone을 지정하지 않으면 timezone이 None이므로 astimezone()을 실행하면 에러가 발생합니다. 따라서 결론은 datetime을 생성할 때 timezone을 지정하는 것입니다.


하지만 이미 생성된 datetime이라면 어떨까..

여기서 방법은 2가지로 나뉩니다.

datetime → time → datetime 으로 변환

먼저 datetime을 time타입으로 변환 시킨 다음, 이 값으로 timezone을 지정하여 datetime객체를 새로 생성하는 방법입니다.

이 방법은 아래에서 설명할 replace()함수가 지원되지 않는 python 버전에서 사용할 수 있습니다.

import datetime
import time

now_dt = datetime.datetime.now()
print(now_dt)

now_t = time.mktime(now_dt.timetuple()) + now_dt.microsecond / 1E6

print(now_t)

c_now_dt = datetime.datetime.fromtimestamp(now_t, datetime.timezone.utc)
print(c_now_dt)

# 결과
# 2017-10-15 18:45:32.357988
# 1508060732.357988
# 2017-10-15 09:45:32.357988+00:00

replace() 사용 (pyhton 3.3 이상)

위 방법은 상당히 귀찮으므로 python 버전이 3.3 이상이면 replace()함수를 사용합니다.

import datetime


now_dt = datetime.datetime.now()
print(now_dt)

c_now_dt = now_dt.replace(tzinfo=datetime.timezone.utc)
print(c_now_dt)

# 결과
# 2017-10-15 18:48:32.402106
# 2017-10-15 18:48:32.402106+00:00

주의점

위 두 결과를 보고 확인이 되듯이 replace()함수를 사용해 timezone을 입력하면 timezone은 변경이 되지만 utc 시간대로 변경되지 않습니다(!!)

아래는 python 3.6대에서 astimezone()도 추가하여 비교한 코드입니다.

import datetime
import time

now_dt = datetime.datetime.now()
print('현재 시간: ', now_dt)

now_t = time.mktime(now_dt.timetuple()) + now_dt.microsecond / 1E6
c_now_dt = datetime.datetime.fromtimestamp(now_t, datetime.timezone.utc)

print('datetime-> time -> datetime 변환시간: ', c_now_dt)

print('replace() 변환시간: ',now_dt.replace(tzinfo=datetime.timezone.utc))
print('astimezone() 변환시간: ',now_dt.astimezone(datetime.timezone.utc))


# 현재 시간:  2017-10-16 19:09:44.162545
# datetime-> time -> datetime 변환시간:  2017-10-16 10:09:44.162545+00:00
# replace() 변환시간:  2017-10-16 19:09:44.162545+00:00
# astimezone() 변환시간:  2017-10-16 10:09:44.162545+00:00


이것처럼 replace()를 사용할 때, utc 시간대로 변경되지 않는 다는 점을 숙지하고 사용해야 합니다.

결론

datetime 생성할떄 timezone과 timedeltal를 이용해서 필요한 타임존 설정을 해주면 모든게 해결됨. (근데 귀찮다)

+ Random Posts