Convert timestamps with offset to datetime obj using strptime

前端 未结 4 516

I am trying to convert time-stamps of the format \"2012-07-24T23:14:29-07:00\" to datetime objects in python using strptime method. The problem is with the time offset at t

相关标签:
4条回答
  • 2020-11-22 04:24

    In Python 3.7+:

    from datetime import datetime
    
    time_str = "2012-07-24T23:14:29-07:00"
    dt_aware = datetime.fromisoformat(time_str)
    print(dt_aware.isoformat('T'))
    # -> 2012-07-24T23:14:29-07:00
    

    In Python 3.2+:

    from datetime import datetime
    
    time_str = "2012-07-24T23:14:29-0700"
    dt_aware = datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S%z')
    print(dt_aware.isoformat('T'))
    # -> 2012-07-24T23:14:29-07:00
    

    Note: Before Python 3.7 this variant didn't support : in the -0700 part (both formats are allowed by rfc 3339). See datetime: add ability to parse RFC 3339 dates and times.

    On older Python versions such as Python 2.7, you could parse the utc offset manually:

    from datetime import datetime
    
    time_str = "2012-07-24T23:14:29-0700"
    # split the utc offset part
    naive_time_str, offset_str = time_str[:-5], time_str[-5:]
    # parse the naive date/time part
    naive_dt = datetime.strptime(naive_time_str, '%Y-%m-%dT%H:%M:%S')
    # parse the utc offset
    offset = int(offset_str[-4:-2])*60 + int(offset_str[-2:])
    if offset_str[0] == "-":
       offset = -offset
    dt = naive_dt.replace(tzinfo=FixedOffset(offset))
    print(dt.isoformat('T'))
    

    where FixedOffset class is defined here.

    0 讨论(0)
  • 2020-11-22 04:29

    With python 3.5.2
    To convert 26 Sep 2000 05:11:00 -0700

    from datetime import datetime    
    dt_obj = datetime.strptime("26 Sep 2000 05:11:00 -0700", '%d %b %Y %H:%M:%S %z')
    

    To convert 2012-07-24T23:14:29 -0700

    dt_obj = datetime.strptime('2012-07-24T23:14:29 -0700', '%Y-%m-%dT%H:%M:%S %z')
    

    Python 3.5.2 doesn't support -07:00 time offset ':' should be removed

    0 讨论(0)
  • 2020-11-22 04:34

    The Python 2 strptime() function indeed does not support the %z format for timezones (because the underlying time.strptime() function doesn't support it). You have two options:

    • Ignore the timezone when parsing with strptime:

      time_obj = datetime.datetime.strptime(time_str[:19], '%Y-%m-%dT%H:%M:%S')
      
    • use the dateutil module, it's parse function does deal with timezones:

      from dateutil.parser import parse
      time_obj = parse(time_str)
      

    Quick demo on the command prompt:

    >>> from dateutil.parser import parse
    >>> parse("2012-07-24T23:14:29-07:00")
    datetime.datetime(2012, 7, 24, 23, 14, 29, tzinfo=tzoffset(None, -25200))
    

    You could also upgrade to Python 3.2 or newer, where timezone support has been improved to the point that %z would work, provided you remove the last : from the input, and the - from before the %z:

    >>> import datetime
    >>> time_str = "2012-07-24T23:14:29-07:00"
    >>> datetime.datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S%z')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
        tt, fraction = _strptime(data_string, format)
      File "/Users/mj/Development/Library/buildout.python/parts/opt/lib/python3.4/_strptime.py", line 337, in _strptime
        (data_string, format))
    ValueError: time data '2012-07-24T23:14:29-07:00' does not match format '%Y-%m-%dT%H:%M:%S%z'
    >>> ''.join(time_str.rsplit(':', 1))
    '2012-07-24T23:14:29-0700'
    >>> datetime.datetime.strptime(''.join(time_str.rsplit(':', 1)), '%Y-%m-%dT%H:%M:%S%z')
    datetime.datetime(2012, 7, 24, 23, 14, 29, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))
    
    0 讨论(0)
  • 2020-11-22 04:42

    ValueError: 'z' is a bad directive in format...

    (note: I have to stick to python 2.7 in my case)

    I have had a similar problem parsing commit dates from the output of git log --date=iso8601 which actually isn't the ISO8601 format (hence the addition of --date=iso8601-strict in a later version).

    Since I am using django I can leverage the utilities there.

    https://github.com/django/django/blob/master/django/utils/dateparse.py

    >>> from django.utils.dateparse import parse_datetime
    >>> parse_datetime('2013-07-23T15:10:59.342107+01:00')
    datetime.datetime(2013, 7, 23, 15, 10, 59, 342107, tzinfo=+0100)
    

    Instead of strptime you could use your own regular expression.

    0 讨论(0)
提交回复
热议问题