Python : Datetime, Timezone, pytz

Joey Lee·2020년 12월 9일
0

Python

목록 보기
11/12

**** [참고 자료]

[중요개념]

  • 파이썬의 datetime.datetime : 날짜(date)와 시간정보(time)로 구성
  • timezone 정보 포함여부에 따라 naive datetime과 aware datetime으로 나누어 짐
  • UTC 시간 -> 현지 시간으로 변경하는 방법

1. Datetime

1) Date

  • 날짜 계산 시,
    -> date2 = date1 + timedelta
    -> timedelta = date1 + date2
import datetime

td = datetime.date(2011, 9, 11)  # 09로 하면 에러 발생
print(td)     # 2011-09-11 출력
tday = datetime.date.today()
print(tday)   # 2020-12-09 출력

# 요일 찾기

# Monday 0 ~ Sunday 6
print(tday.weekday())
# Monday 1 ~ Sunday 7
print(tday.isoweekday())

# 오늘 -7일 날짜 구하기
tday = datetime.date.today()
tdelta = datetime.timedelta(days=7)

print(tday + tdelta)   # 2020-12-02 출력

# 생일까지 남은 날짜 구하기
bday = datetime.date(2020, 12, 25)

till_bday = bday - tday
print(till_bday)        # 16 days, 0:00:00
print(till_bday.days)   # 16
print(till_bday.total_seconds())   # 1382400.0

2) Time

t = datetime.time(9, 30, 45, 100000)
print(t)         # 09:30:45.100000
print(t.hour)    # 9

dt = datetime.datetime(2020, 12, 10, 12, 30, 00, 100000)
print(dt)         # 2020-12-10 12:30:00.100000
print(dt.date())  # 2020-12-10
print(dt.time())  # 12:30:00.100000

2. Naive & Aware Datetime

1) Naive Datetime

dt_today = datetime.datetime.today()     # current local datetime (tz=none)
dt_now = datetime.datetime.now()         # current local datetime (can add timezone)
dt_utcnow = datetime.datetime.utcnow()   # current utc datetime (tz=none)

print(dt_today)
> 2020-12-09 21:42:57.328324

print(dt_now)
> 2020-12-09 21:42:57.328454

print(dt_utcnow)
> 2020-12-09 12:42:57.328491

2) Aware Datetime으로 바꾸기

  • Timezone 쓸 때는 pytz 쓸 것을 권고
  • datetime 메소드에 tzinfo, now 메소드에는 tz로 타임존을 정의할 수 있음
  • 타임존이 정의된 aware datetime는 datetime에서 +00:00가 추가된 결과값을 리턴
import datetime
import pytz

dt = datetime.datetime(2016, 7, 24, 12, 30, 45, tzinfo=pytz.UTC)

dt_utcnow2 = datetime.datetime.utcnow().replace(tzinfo=pytz.UTC)

# UTC 기준 현재 시간 구하기
dt_utcnow = datetime.datetime.now(tz=pytz.UTC)

# 세 개 다 출력하면 대략 아래 모습
> 2020-12-10 12:30:00.100000+00:00

# UTC Now 시간 -> US/Mountain 타임존 기준 시간으로 변환
dt_mtn = dt_utcnow.astimezone(pytz.timezone('US/Mountain'))
print(dt_mtn)
> 2020-12-09 06:33:42.377148-07:00

# Naive datetime으로 시간대 바꾸면 에러 발생 (당연히! 기준이 없으니)
dt_mtn = datetime.datetime.now()
dt_east = dt.mtn.astimezone(pytz.timezone('US/Eastern'))
> ValueError : astimezone() cannot be applied to a naive datetime

# Naive -> Aware datetime하는 방법 (타임존 추가)
dt_mtn = datetime.datetime.now()
mtn_tz = pytz.timezone('US/Mountain')
dt_mtn = mtn_tz.localize(dt_mtn)
dt_east = dt_mtn.astimezone(pytz.timezone('US/Eastern'))
print(dt_east)     # 이제는 워킹한다

3) Str <-> Datetime 변환하기

  • strftime : Datetime to String
  • strptime : String to Datetime
# Datetime -> Str
print(dt_mtn.strftime('%B %d, %Y'))

# Str -> Datetime
dt_str = 'July 24, 2016'
dt = datetime.datetime.strptime(dt_str, '%B %d, %Y')
print(dt)

3. UTC -> 현지 시간으로 변경하기

1) pytz 이용

  • aware datetime에서 astimezone메소드를 호출하여 인자로 전달된 타임존 기준 시간으로 변경해 줌
import pytz
import datetime

# UTC 현재 시간
dt = datetime.datetime.now(datetime.timezone.utc)
> datetime.datetime(2020, 12, 19, 7, 12, 44, 334126, tzinfo=datetime.timezone.utc)

# 현지 타임존 정보
KST = pytz.timezone('Asia/Seoul')
> <DstTzInfo 'Asia/Seoul' LMT+8:28:00 STD>

# UTC 현재 시간 -> 현지 시간으로 변경
dt_korea = dt.astimezone(KST)
> datetime.datetime(2020, 12, 19, 16, 12, 44, 334126, tzinfo=<DstTzInfo 'Asia/Seoul' KST+9:00:00 STD>)

# 각 datetime의 tzinfo 확인
dt.tzinfo
> <UTC>
dt_korea.tzinfo
> <DstTzInfo 'Asia/Seoul' KST+9:00:00 STD>

2) django.utils.timezone 이용

  • timezone은 장고에 설정되어진 사용자의 타임존 정보를 바탕으로 현지 시간으로 변환해 줌
  • localtime 메소드는 Convert an aware datetime.datetime to local time 역할을 함

위의 코드에 추가해서, 아래와 같음.
아래 코드는 설정된 타임존이 UTC이기에 시간 변동이 없음

from django.utils import timezone

# UTC 현재 시간 -> 현지 시간으로 변경
dt_local = timezone.localtime(dt)
> datetime.datetime(2020, 12, 19, 7, 12, 44, 334126, tzinfo=<UTC>)
def localtime(value=None, timezone=None):
    """
    Convert an aware datetime.datetime to local time.

    Only aware datetimes are allowed. When value is omitted, it defaults to
    now().

    Local time is defined by the current time zone, unless another time zone
    is specified.
    """
    if value is None:
        value = now()
    if timezone is None:
        timezone = get_current_timezone()
    # Emulate the behavior of astimezone() on Python < 3.6.
    if is_naive(value):
        raise ValueError("localtime() cannot be applied to a naive datetime")
    return value.astimezone(timezone)
profile
안녕하세요!

0개의 댓글