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 the end(-07:00). Without the offset i can successfully do
time_str = "2012-07-24T23:14:29" time_obj=datetime.datetime.strptime(time_str,'%Y-%m-%dT%H:%M:%S')
But with the offset i tried
time_str = "2012-07-24T23:14:29-07:00" time_obj=datetime.datetime.strptime(time_str,'%Y-%m-%dT%H:%M:%S-%z').
But it gives a Value error saying "z" is a bad directive.
Any ideas for a work around?
The strptime() function in Python is used to format and return a string representation of date and time. It takes in the date, time, or both as an input, and parses it according to the directives given to it.
strptime is short for "parse time" where strftime is for "formatting time". That is, strptime is the opposite of strftime though they use, conveniently, the same formatting specification.
Python time strptime() MethodThe format parameter uses the same directives as those used by strftime(); it defaults to "%a %b %d %H:%M:%S %Y" which matches the formatting returned by ctime(). If string cannot be parsed according to format, or if it has excess data after parsing, ValueError is raised.
DESCRIPTION. The strptime() function converts the character string pointed to by buf to values which are stored in the tm structure pointed to by tm, using the format specified by format. The format is composed of zero or more directives.
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)))
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With