UTC 시간과 파이썬 : 기본편
UTC 를 알아보고, 파이썬에서 UTC 시간을 어떻게 다루는지
GMT, UTC 란
GMT (Greenwich Mean Time) 는 영국 런던의 그리니치 천문대에서 태양 위치를 측정하여 만든 표준시간 입니다.
UTC (Coordinated Universal Time) 는 GMT에 기반을 두고 있으나, 정밀한 원자시계를 사용하여 보다 정확하게 조정된 시간입니다. 1972 년 1월 1일부터 시행된 국제 표준시이며, 1970년 1월 1일 자정을 0 밀리 초를 기준 삼아 시간의 흐름을 밀리 초로 누적 계산합니다. 이러한 누적시간을 타임스탬프(TimeStamp) 라고 합니다.
UTC 는 컴퓨터 시스템과 네트워킹에서 데이터 기록, 로그 관리, 시간 동기화 등에 중요하게 사용됩니다. 아래와 같이 여러가지 프로그래밍 언어에서 간단한 코드를 통해 UTC 가 사용되고 있음을 확인 할 수 있습니다.
const Jan01_1970 = new Date(0);
Jan01_1970.valueOf() // 0
const now = new Date();
now.valueOf() // 170........ 1970-01-01 이후 누적 밀리 초
from datetime import datetime
now = datetime.now()
print(now.timestamp()) # 170........ 1970-01-01 이후 누적 밀리 초
ISO 8601
그렇다면 UTC 는 어떻게 표기 해야 할까요? 날짜, 시간, 그리고 시간대를 명확하고 일관된 형식으로 표현하기 위해 ISO 8601 표준을 따르면 됩니다. UTC 시간은 ISO 8601 표준에 따라 아래와 같이 표기될 수 있습니다.
2023-12-24T15:00:00Z
2023-12-24T15:00:00+00:00
- 여기서 중간에
T
는 날짜와 시간을 구분하는 구분자입니다. - 끝에
Z
는 Zero time zone 즉, UTC 를 의미합니다. -
Z
는 시간대 오프셋으로 표현하면+00:00
으로 표현할 수 있습니다.
시간대 오프셋
많은 국가와 지역은 고유의 표준 시간대를 가지고 있으며, 이는 UTC 오프셋으로 정의됩니다. 예를 들어, 한국 표준시(KST)는 UTC+9, 뉴욕(동부 표준시, EST)는 UTC-5입니다.
지역 시간은 UTC 시간에 해당 지역의 오프셋을 더하거나 빼서 계산합니다. 예를 들어, UTC 시간이 0인 (= UTC) 영국이 크리스마스 이브 = 2023-12-24 일 15:00 시 이면, 시간대 오프셋이 +09:00
인 한국은 크리스마스 당일 = 2023-12-25 일 0시 입니다.
2023-12-24T15:00:00Z
2023-12-25T00:00:00+09:00
파이썬에서 UTC
Python에서 UTC 시간을 다루기 위한 datetime
모듈 주요 함수들은 다음과 같습니다.
datetime.now()
datetime.utcnow()
-
pytz
라이브러리
datetime.now()
현재 시스템의 로컬 시스템 시간을 반환합니다. 기본 호출(인수 없이)은 시간대 정보가 없는 naive datetime 객체를 반환합니다. 즉, datetime.now()
로 생성된 datetime 객체는 시간대를 알 수 없습니다. UTC 가 있는 구체적인 시간대와 비교하거나 변환하는 것이 명시적으로는 불가능합니다. 시간대 정보는 tzinfo
속성으로 확인 가능합니다.
from datetime import datetime
now = datetime.now()
print(now) # 2023-12-25 00:00:00.000000
print(now.tzinfo) # None
datetime.utcnow()
이 함수는 현재 UTC 시간을 반환합니다. 하지만 이 함수도 시간대 정보가 없는 naive datetime 객체를 반환합니다. 즉, 제대로 된 UTC 활용이 어렵습니다. 그리고 python 3.12 버전 부터는 deprecated 되었기 때문에 사용하지 않는 것을 권장 합니다.
from datetime import datetime, UTC
utc_now = datetime.utcnow()
print(utc_now) # 2023-12-24 15:00:00.000000
print(utc_now.tzinfo) # None
어웨어와 나이브 객체
날짜와 시간 객체는 시간대 정보를 포함하는지에 따라 어웨어(aware)와 나이브(naive)로 분류될 수 있습니다.
어웨어(aware)
어웨어 객체는 다른 어웨어 객체와의 상대적인 위치를 파악할 수 있습니다. 이는 일광 절약 시간(=DST), 썸머 타임 적용 또한 가능하게 합니다. 즉, 명확한 시간의 사용 및 계산이 가능합니다.
나이브(naive)
나이브 객체는 다른 시간과 상대적인 위치를 파악할 충분한 정보를 포함하지 않습니다. 나이브 객체가 UTC, 지역 시간 또는 다른 시간대의 시간 중 어느 것을 나타내는지는 순전히 프로그램에 달려있습니다. 나이브 객체는 이해하기 쉽고 작업하기 쉽지만, 시간을 다루는 로직에서 문제가 생길 수 있습니다.
timezone 추가하기
그렇다면 UTC 오프셋이 올바르게 적용된 시간 객체를 만드는 방법은 무엇일까요? timezone 이라는 오프셋을 의미하는 객체를 시간을 생성 할때 추가해주면 됩니다. UTC 0 을 의미하는 timezone.utc
또는 python 3.12 버전에서는 UTC
라는 별도의 상수값이 추가되어 이를 사용해도 됩니다.
from datetime import datetime, timezone, UTC
now = datetime.now(timezone.utc)
print(now) # 2023-12-24 15:00:00.000000+00:00
print(now.tzinfo) # UTC
+09:00 한국 오프셋 설정
UTC+00:00 이외의 시간대를 표시 할 때는 오프셋 시간 만큼 timedelta
객체를 사용하여, timezone 객체를 직접 생성해서 사용하면 됩니다. +09:00
끝에 시간대 오프셋이 추가되어 출력되는 것을 확인 할 수 있습니다. 또한 tzinfo
속성값이 설정 된것을 확인 가능합니다.
from datetime import datetime, timezone, timedelta
tz = timezone(timedelta(hours=9))
now = datetime.now(tz)
print(now) # 2023-12-25 00:00:00.000000+09:00
print(now.tzinfo) # UTC+09:00
pytz 라이브러리
여러나라의 timezone 을 하나씩 직접 시간 오프셋을 이용해서 만든다고 생각해봅시다. 어떤 나라의 어떤 도시는 어떤 오프셋을 가지는지 일일히 알아야 합니다. 이때 약 500 개 이상의 UTC 정보를 제공해주는 pytz
라이브러리를 사용하면 UTC 를 포함한 다양한 시간대를 쉽게 다룰 수 있습니다.
pip install pytz
from datetime import datetime
from pytz import timezone, all_timezones
tz = timezone("Asia/Tokyo")
now = datetime.now(tz)
print(now) # 2023-12-25 00:00:00.000000+09:00
print(now.tzinfo) # Asia/Tokyo
print(all_timezones) # 지원하는 시간대 문자열 확인 가능
UTC 정리
UTC 는 시간을 국제 표준시이며, 많은 시스템과 프로그래밍에서도 이를 사용하고 활용하고 있습니다. UTC 를 정확하게 표기 하기 위해서는 ISO 8601 를 따르면 됩니다. 하지만 위에서 출력된 결과는 어떤가요? 위에서 봤던 코드에는 함정이 있습니다. 다시 한번 잘 보시길 바랍니다.
과연? ISO 표준을 잘 준수해서 표현되고 있는지…
# 코드에서 만든 시간
2023-12-24 15:00:00.000000+00:00
2023-12-25 00:00:00.000000+09:00
# ISO 표준
2023-12-24T15:00:00.000000Z
2023-12-25T00:00:00.000000+09:00
날짜와 시간 사이에 구분 문자열인 T
가 빠져있는 것을 확인 할 수 있습니다. 이렇듯 표준과 다른 사소한 표기가 가져오는 몇 가지 문제가 있습니다. 🥲
- 날짜와 시간 구분자
- 시간대 표현법
- 시간대 오프셋을 고려해서 계산
실제 업무에서 구현하면서 만났던 문제는 다음편 UTC 시간과 파이썬 : 유의사항에서 적도록 하겠습니다.