본문으로 바로가기

datetime과 시간대

category Language/Python 2023. 1. 15. 15:14
728x90
반응형

목차

    DateTime

    datetime은 날짜와 시간 정보를 함께 저장하는 클래스이다. 현재시간을 나타내는 datetime.now() 메서드를 통해 알아보자.

    from datetime import datetime
    
    ct = datetime.now()
    
    print(ct)
    
    # Output
    # 2023-01-15 13:27:40.177895
    

    날짜 정보와 시간 정보를 접근할 수 있는 속성을 가진다. 날짜 정보는 year, month, day 시간 정보는 time, second, microsecond이다.

    print(ct.year, ct.month, ct.day) # 2023 1 15
    print(ct.minute, ct.second, ct.microsecond) # 27 40 177895
    

    위와 같이 속성에 접근하면 속성을 매번 따로따로 작성해야 하는 공수가 드는데 날짜 정보 혹은 시간 정보만 확인할 수 있는 메서드도 존재한다.

    print(ct.date()) # 2023-01-15
    print(ct.time()) # 13:27:40.177895
    

     

    weekday

    오늘이 무슨 요일인지 확인하는 기능도 제공한다. weekday() 메서드를 이용하면 되고 0 ~ 6을 반환하며 0은 월요일 6은 일요이다. 나머지 요일은 0부터 순차적으로 증가한다.

    print(ct.weekday()) # 6
    

     

    strftime

     많이 사용되는 형태가 있는데 strftime이다. String Format Time이라고도 불리며 시간 형태를 바꿔서 출력할 수 있다. 시간 형태를 바꿔서 출력하는 게 무슨 의미가 있나라는 생각이 들 수 있는데 예를 들어 요구사항에 따라 파일명이나 폴더명을 저장해야 하는 경우 유용하게 사용할 수 있다. 정확한 String Format 문자열의 참고는 이곳에서 참고하자. 아래는 연, 월, 일, 시, 분, 초에 대해 필자가 이해한 대로 정리한 내용이다

    %y ‘연’를 뜻하며, 2023년인 경우 23년을 출력함
    %Y ‘연’를 뜻하며, 2023년인 경우 2023년을 출력함
    %m ‘월’을 뜻하며, 01..12 형태로 출력한다
    %d ‘일’을 뜻하며, 01 ~ 31 형태로 출력한다
    %H ‘시’를 뜻하며, 00 ~23 형태로 출력한다.
    %M ‘분’을 뜻하며, 00 ~ 59 형태로 출력한다.
    %S ‘초’를 뜻하며, 00 ~ 59 형태로 출력한다.
    # Example
    print(ct.strftime('%y-%m-%d')) # 23-01-15
    print(ct.strftime('%Y-%m-%d')) # 2023-01-15
    print(ct.strftime("%H:%M:%S")) # 13:53:17
    


    strptime

    strptime이라는 메서드는 입력된 문자열 형태로부터 datetime 객체를 만들어 반환한다. 문자열 형태가 datetime으로 변경할 수 없는 경우 ValuError가 발생한다.

    string = "2023 01 15"
    
    to_datetime = datetime.strptime(string, "%Y %m %d")
    
    print(to_datetime) # 2023-01-15 00:00:00
    


    시간대를 적용하자

    시간에 관련된 처리는 반드시 시간대를 고려해야 한다. 시간대는 영국의 그리니치 천문대를 기준으로 지구 자전에 따른 지역 사이에 생기는 낮과 밤의 차이를 인위적으로 조정하기 위해 고안된 시간의 구분 선을 일컫는다.

     

    나라 또는 지역마다 시각이 다르기 때문에 이를 명시적으로 처리해야 한다.

     

    나라 또는 지역마다 시간대가 다른데 어떻게 대처할 수 있을까?

     

    UTC (협정 세계시)를 이용해야 한다. UTC는 국제적인 표준 시간의 기준으로 쓰이는 시각을 일컫는다. UTC 보다 빠르면 + 를 UTC보다 느리면 -를 표기해서 구분한다.

     

    datetime에서 Python코드를 실행하는 서버나 컴퓨터의 시간에 상관없이 utc를 출력하는 방법은 다음과 같다

    from datetime import datetime
    print(datetime.utcnow()) # 2023-01-15 05:11:51.661434
    

    예를 들어 UTC를 한국 표준시인 KST로 변환하려면 9시간을 더하면 되므로 다음과 같이 처리한다.

    from datetime import datetime, timedelta
    
    print(datetime.utcnow() + timedelta(hours=9) # 2023-01-15 14:11:51.66163
    

    아래와 같이 datetime에 존재하는 astimezone 메서드를 이용해 timzone을 설정할 수도 있다.

    from datetime import datetime, timezone, timedelta
    
    UTC = timezone(timedelta())
    KST = timezone(timedelta(hours=9))
    
    d = datetime(2023, 1, 15, 0, 0, 0)
    print(d.astimezone(UTC)) # 2023-01-14 15:00:00+00:00
    print(d.astimezone(KST)) # 2023-01-15 00:00:00+09:00
    


    시간대 명시하기 Aware와 Naive

    용어가 낯설지만 간단히 정리하면 Aware는 시간대를 포함하고 Naive는 시간대를 포함하지 않는 정도로 이해하면 된다.

    # Navie
    datetime.datetime(2023,01,15,13,0,0)
    
    # Aware
    datetime.datetime(2023, 01, 15, 13, 0, 0, tzionf=<UTC>)
    

    주목해야 될 점은 Naive는 어느 시간대를 기준으로 하는 시각인지 모르기 때문에 Aware 방식을 이용해야 한다는 점이다. 예를 들어 datetime만을 이용하여 시간을 표시한다고 해보자.

    print(datetime.now()) # 2023-01-15 14:44:41.343959
    

    위 코드가 어느 시간대를 기준으로 출력되었는지 알 수 있을까? 시간만 보고 어느 시간대를 기준으로 하는지 알 수가 없다. 앞서 datetime에 시간대를 조정하기 위해 timedelta를 써서 시간대를 조정했었는데 이보다 쉽게 해주는 방법은 pytz 라이브러리를 이용하자. datetime으로부터 utc를 구하고 이에 대하여 시간대를 명시하기 위한 방법으로 다음과 같이 사용할 수 있다.

    from datetime import datetime, timezone, timedelta
    from pytz import timezone, utc
    
    utcnow = datetime.utcnow()
    
    print(utcnow)
    
    KST = timezone("Asia/Seoul")
    print(KST.localize(utcnow))
    
    # OutPut
    # 2023-01-15 05:48:47.491353
    # 2023-01-15 05:48:47.491353+09:00
    

    KST를 적용한 시간의 결과는 여전히 utc를 나타내지만 aware 방식을 통해 해당 시간이 utc를 기준으로 어느 시간대가 적용되었는지 알 수 있게 되었다. KST를 적용한 시간 자체를 보려면 다음과 같은 방식으로 사용한다.

    from datetime import datetime, timezone, timedelta
    from pytz import timezone, utc
    
    utcnow = datetime.utcnow()
    
    KST = timezone("Asia/Seoul")
    
    pytz_utc = utc.localize(utcnow)
    print(pytz_utc.astimezone(KST)) # 2023-01-15 14:53:00.479618+09:00
    

    위 코드에서 표출되는 시간 정보는 KST가 적용된 시간이다.

    여차저차했지만 결론은 UTC를 기준으로..

    2023-01-15 14:53:00.479618+09:00
    

    앞서 위의 정보는 KST가 적용된 시간이라고 언급했다. 그런데 시/분/초 와 시간대가 더해진 정보만을 보고 UTC로부터 더해진 한국 시간인지 다른 시간대로부터 더해진 한국 시간인지 직관적으로 이해할 수 있을까? 적어도 나는 어렵다. 그러니 시간에 관련된 표기는 utc를 기준으로 timzone을 표기하는 방법을 사용하도록 하자. 예를 들어

    2023-01-15 06:01:08.726238+09:00
    

    위와 같은 경우 시/분/초는 utc이고 timezone 정보를 통해서 한국 시간대를 적용해서 표출해야 하는 구나의 느낌이다.


    728x90
    반응형