ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Python] 문자열을 Datetime으로 변경하는 방법
    언어/파이썬 & 장고 2019. 2. 2. 16:50

    문자열로 되어 있는 시간을 Datetime 객체로 변경하는 방법은 많이 찾아 볼 수 있습니다. 여기서는 기존에 존재하는 방법과 추가 설치 모듈로 좀 더 간편하게 사용하는 방법을 설명하겠습니다.

    1. Datetime

    파이썬에 내장되어 있는 Datetime 패키지를 사용하여 아래와 같이 변환을 할 수 있습니다.

    import datetime
    
    date_time_str = '2018-06-29 08:15:27.243860'  
    date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f')
    
    print('Date-time:', date_time_obj)
    
    
    # Date-time: 2018-06-29 08:15:27.243860


    흔히 사용하는 포맷은 ISO 8601으로  YYYY-MM-DDTHH:MM:SS.mmmmmm 와 같이 표현하고 있습니다. 이와 같은 포맷만 들어온다면 그대로 사용해도 무방하지만 아래와 같이 여러 타입이 존재한다면 고려할 사항이 많아집니다.

    "Jun 28 2018 at 7:40AM" -> "%b %d %Y at %I:%M%p"
    "September 18, 2017, 22:19:55" -> "%B %d, %Y, %H:%M:%S"
    "Sun,05/12/99,12:30PM" -> "%a,%d/%m/%y,%I:%M%p"
    "Mon, 21 March, 2015" -> "%a, %d %B, %Y"
    "2018-03-12T10:12:45Z" -> "%Y-%m-%dT%H:%M:%SZ"

    timezone 지정

    위처럼 문자열을 datetime 객체로 변환하거나 현재 날짜+시간을 호출하면 현재 로컬시간을 기준으로 호출이 됩니다.

    now = datetime.datetime.now()
    print(now)
    
    
    # 2019-02-02 15:54:07.244639


    여기서 구한 현재 시간을 뉴욕시간대로 변경하고자 하면 아래와 같이 복잡한 절차를 거치게 됩니다. 또한 현재 시간이 뉴욕시간대로 변환되지 않고 timezone만 추가된 형태를 확인할 수 있습니다.

    import datetime as dt
    import pytz
    
    date_time_obj = dt.datetime.now()
    
    print('now:', date_time_obj)
    
    timezone = pytz.timezone('America/New_York')
    timezone_date_time_obj = timezone.localize(date_time_obj)
    
    print(timezone_date_time_obj)
    print(timezone_date_time_obj.tzinfo)
    
    
    # now: 2019-02-02 15:56:15.197103
    # 2019-02-02 15:56:15.197103-05:00
    # America/New_York


    datetime 패키지로만 충분히 변환하거나 시간대를 바꿀 수 있지만 다른 모듈을 설치하면 좀 더 간편하게 사용할 수 있습니다.

    2. dateutil

    dateutil 모듈을 설치하여 사용하면 문자열의 시간 포맷을 걱정할 필요가 없습니다.

    from dateutil.parser import parse
    
    date_array = [
        '2018-06-29 08:15:27.243860',
        'Jun 28 2018  7:40AM',
        'Jun 28 2018 at 7:40AM',
        'September 18, 2017, 22:19:55',
        'Sun, 05/12/1999, 12:30PM',
        'Mon, 21 March, 2015',
        '2018-03-12T10:12:45Z',
        '2018-06-29 17:08:00.586525+00:00',
        '2018-06-29 17:08:00.586525+05:00',
        'Tuesday , 6th September, 2017 at 4:30pm'
    ]
    
    for date in date_array:
        print('Parsing: ' + date)
        dt = parse(date)
        print(dt.date())
        print(dt.time())
        print(dt.tzinfo)
        print()
    
    
    
    # Parsing: 2018-06-29 08:15:27.243860
    # 2018-06-29
    # 08:15:27.243860
    # None
    
    # Parsing: Jun 28 2018  7:40AM
    # 2018-06-28
    # 07:40:00
    # None
    
    # Parsing: Jun 28 2018 at 7:40AM
    # 2018-06-28
    # 07:40:00
    # None
    
    # Parsing: September 18, 2017, 22:19:55
    # 2017-09-18
    # 22:19:55
    # None
    
    # Parsing: Sun, 05/12/1999, 12:30PM
    # 1999-05-12
    # 12:30:00
    # None
    
    # Parsing: Mon, 21 March, 2015
    # 2015-03-21
    # 00:00:00
    # None
    
    # Parsing: 2018-03-12T10:12:45Z
    # 2018-03-12
    # 10:12:45
    # tzutc()
    
    # Parsing: 2018-06-29 17:08:00.586525+00:00
    # 2018-06-29
    # 17:08:00.586525
    # tzutc()
    
    # Parsing: 2018-06-29 17:08:00.586525+05:00
    # 2018-06-29
    # 17:08:00.586525
    # tzoffset(None, 18000)
    
    # Parsing: Tuesday , 6th September, 2017 at 4:30pm
    # 2017-09-06
    # 16:30:00
    # None


    위 예시처럼 시간포맷을 알 필요가 없다는 장점이 있지만 timezone을 지정하지 않으면 로컬 시간을 바라보고 있는 것을 확인할 수 있습니다.

    3. maya

    마야 또한 위의 dateutil 모듈과 같이 시간 포맷에 상관없이 변환할 수 있습니다.

    import maya
    
    date_array = [  
        '2018-06-29 08:15:27.243860',
        'Jun 28 2018  7:40AM',
        'Jun 28 2018 at 7:40AM',
        'September 18, 2017, 22:19:55',
        'Sun, 05/12/1999, 12:30PM',
        'Mon, 21 March, 2015',
        '2018-03-12T10:12:45Z',
        '2018-06-29 17:08:00.586525+00:00',
        '2018-06-29 17:08:00.586525+05:00',
        'Tuesday , 6th September, 2017 at 4:30pm'
    ]
    
    for date in date_array:  
        print('Parsing: ' + date)
        dt = maya.parse(date).datetime()
        print(dt)
        print(dt.date())
        print(dt.time())
        print(dt.tzinfo)
        print()
    
    
    # Parsing: 2018-06-29 08:15:27.243860
    # 2018-06-29 08:15:27.243860+00:00
    # 2018-06-29
    # 08:15:27.243860
    # UTC
    
    # Parsing: Jun 28 2018  7:40AM
    # 2018-06-28 07:40:00+00:00
    # 2018-06-28
    # 07:40:00
    # UTC
    
    # Parsing: Jun 28 2018 at 7:40AM
    # 2018-06-28 07:40:00+00:00
    # 2018-06-28
    # 07:40:00
    # UTC
    
    # Parsing: September 18, 2017, 22:19:55
    # 2017-09-18 22:19:55+00:00
    # 2017-09-18
    # 22:19:55
    # UTC
    
    # Parsing: Sun, 05/12/1999, 12:30PM
    # 1999-05-12 12:30:00+00:00
    # 1999-05-12
    # 12:30:00
    # UTC
    
    # Parsing: Mon, 21 March, 2015
    # 2015-03-21 00:00:00+00:00
    # 2015-03-21
    # 00:00:00
    # UTC
    
    # Parsing: 2018-03-12T10:12:45Z
    # 2018-03-12 10:12:45+00:00
    # 2018-03-12
    # 10:12:45
    # UTC
    
    # Parsing: 2018-06-29 17:08:00.586525+00:00
    # 2018-06-29 17:08:00.586525+00:00
    # 2018-06-29
    # 17:08:00.586525
    # UTC
    
    # Parsing: 2018-06-29 17:08:00.586525+05:00
    # 2018-06-29 12:08:00.586525+00:00
    # 2018-06-29
    # 12:08:00.586525
    # UTC
    
    # Parsing: Tuesday , 6th September, 2017 at 4:30pm
    # 2017-09-06 16:30:00+00:00
    # 2017-09-06
    # 16:30:00
    # UTC


    dateutil과 다르게 maya는 로컬시간을 바라보지 않고 기본적으로 UTC로 지정합니다.

    dateutil과 maya의 차이점

    두 모듈은 비슷해 보이지만 timezone에 대해 아주 큰 차이가 있습니다.

    import maya
    import dateutil.parser
    
    date_array = [  
        '2018-06-29 17:08:00.586525+05:00',
        '2018-06-29 17:08:00.586525',
    ]
    
    
    for date in date_array:  
        print('Parsing: ' + date)
        maya_dt = maya.parse(date).datetime()
        dateutil_dt = dateutil.parser.parse(date)
    
        print('maya: ')
        print(maya_dt)
        print(maya_dt.tzinfo)
    
        print('dateutil: ')
        print(dateutil_dt)
        print(dateutil_dt.tzinfo)
    
        print()
    
    
    # Parsing: 2018-06-29 17:08:00.586525+05:00
    # maya: 
    # 2018-06-29 12:08:00.586525+00:00
    # UTC
    
    
    # dateutil: 
    # 2018-06-29 17:08:00.586525+05:00
    # tzoffset(None, 18000)
    
    # Parsing: 2018-06-29 17:08:00.586525
    # maya: 
    # 2018-06-29 17:08:00.586525+00:00
    # UTC
    
    
    # dateutil: 
    # 2018-06-29 17:08:00.586525
    # None


    maya의 경우는 문자열에 존재하는 +05:00을 계산하여 timezone을 UTC로 세팅합니다. 위의 경우 17시에 +05:00가 존재하여 5시간을 뺀 후, timezone을 UTC라고 보여주고 있습니다. 반면 dateutil은 시간계산을 하지 않고 +05:00을 저장하게 됩니다. 

    또한 timezone을 변경하거나 세팅할 때도 큰 차이가 존재합니다.

    import maya
    import dateutil.parser
    import pytz
    import dateutil
    
    date = '2018-06-29 17:08:00.586525'
    
    print('maya: ')
    maya_dt = maya.parse(date)
    print('parsing: ', maya_dt.datetime())
    maya_dt = maya_dt.datetime(to_timezone='America/New_York', naive=False)
    
    
    print('(timezone) America/New_York: ', maya_dt)
    print(maya_dt.tzinfo)
    
    print('------------------')
    
    print('dateutil: ')
    dateutil_dt = dateutil.parser.parse(date)
    print('parsing: ', dateutil_dt)
    
    timezone = pytz.timezone('America/New_York')
    dateutil_dt = timezone.localize(dateutil_dt)
    
    print('(timezone) America/New_York: ', dateutil_dt)
    print(timezone)
    
    
    
    
    # maya: 
    # parsing:  2018-06-29 17:08:00.586525+00:00
    # (timezone) America/New_York:  2018-06-29 13:08:00.586525-04:00
    # America/New_York
    # ------------------
    # dateutil: 
    # parsing:  2018-06-29 17:08:00.586525
    # (timezone) America/New_York:  2018-06-29 17:08:00.586525-04:00
    # America/New_York


    maya의 경우, 파싱한 시간대에서 지정한 timezone의 시간만큼 계산하여 보여주지만 dateutil의 경우 datetime과 같이 시간은 계산하지 않고 timezone만 붙여서 보여주고 있습니다.

    결론

    문자열에서 datetime 객체로 변환하는 것은 third-party인 maya나 dateutil을 사용하는 것이 좋습니다. 또한 timezone을 변경하거나 각 다르게 사용할 경우, UTC로 변환하여 실행하는 서버 및 로컬의 시간대를 사용하지 않도록 하는 것이 중요합니다.

    댓글