This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Python strptime() and timezones?
'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
Maybe I'm missing something but can anyone spot why this doesn't validate properly?
The strptime() function cannot handle %Z timezone parsing very well. Only UTC and GMT are really supported, and the current value of time.tzname. See the strptime documenation:
Support for the %Z directive is based on the values contained in tzname and whether daylight is true. Because of this, it is platform-specific except for recognizing UTC and GMT which are always known (and are considered to be non-daylight savings timezones).
Removing the EST part of your input and the %Z part of your format string makes things work:
>>> import time
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM EST', '%A, %B %d, %Y %I:%M:%S %p %Z')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 454, in _strptime_time
return _strptime(data_string, format)[0]
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Saturday, December 22, 2012 1:22:24 PM EST' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM', '%A, %B %d, %Y %I:%M:%S %p')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=-1)
or replacing the timezone EST with GMT:
>>> time.strptime('Saturday, December 22, 2012 1:22:24 PM GMT', '%A, %B %d, %Y %I:%M:%S %p %Z')
time.struct_time(tm_year=2012, tm_mon=12, tm_mday=22, tm_hour=13, tm_min=22, tm_sec=24, tm_wday=5, tm_yday=357, tm_isdst=0)
To parse strings with a timezone other than time.tzname, GMT or UTC, use a different date parsing library. The dateutil library has an excellent parse function that handles timezones properly:
>>> from dateutil.parser import parse
>>> parse('Saturday, December 22, 2012 1:22:24 PM EST', tzinfos={'EST': -18000})
datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset(u'EST', -18000))
When using dateutil.parser.parse() you do have to provide your own timezone offsets for your format though.
You can save yourself a lot of trouble and use dateutil.
In [1]: from dateutil import parser
In [2]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST')
Out[2]: datetime.datetime(2012, 12, 22, 13, 22, 24)
As for the ambiguity pointed out by eumiro, you could add a tzinfo argument:
In [3]: parser.parse('Saturday, December 22, 2012 1:22:24 PM EST',tzinfos={'EST':-5*3600})
Out[3]: datetime.datetime(2012, 12, 22, 13, 22, 24, tzinfo=tzoffset('EST', -18000))
As #root suggested dateutil.parser is the robust way to parse date, but just to clarify about the issue here
I just saw the code in _strptime.py and it seems the supported time zones are
["utc", "gmt", time.tzname[0].lower()]
and in case, the current locale timezone supports daylight saving, it would append
time.tzname[0].lower() to the above list.
So when using strptime, ensure that the timezone on which you are parsing the date supports the source timezone
Here is the code for reference
def __calc_timezone(self):
# Set self.timezone by using time.tzname.
# Do not worry about possibility of time.tzname[0] == timetzname[1]
# and time.daylight; handle that in strptime .
try:
time.tzset()
except AttributeError:
pass
no_saving = frozenset(["utc", "gmt", time.tzname[0].lower()])
if time.daylight:
has_saving = frozenset([time.tzname[1].lower()])
else:
has_saving = frozenset()
self.timezone = (no_saving, has_saving)
Most likely your locale timezone is empty, e.g. %Z evaluates to ''
You can test this by:
>>> fmt = '%A, %B %d, %Y %I:%M:%S %p %Z'
>>> datetime.strptime(datetime.strftime(datetime.now(), fmt), fmt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Friday, December 28, 2012 11:34:35 AM ' does not match format '%A, %B %d, %Y %I:%M:%S %p %Z'
Related
I am getting the following error:
ValueError: time data 'Tue, 17 Jul 2018 11:55:34 EDT' does not match format '%a, %d %b %Y %H:%M:%S %Z'
Code:
import datetime
dt = datetime.datetime.strptime('Tue, 17 Jul 2018 11:55:34 EDT', '%a, %d %b %Y %H:%M:%S %Z')
print(dt.timestamp())
Am I missing something here?
EDT is not identified as a valid timezone string. You may use something other intelligent parser and than automatically return the datetime object without you explicitly specifying the format. My suggestion is to go up with dateutil
>>> from dateutil import parser
>>> parser.parse('Tue, 17 Jul 2018 11:55:34 EDT')
datetime.datetime(2018, 7, 17, 11, 55, 34)
I have a string like 23 July 1914 and want to convert it to 23/07/1914 date format.
But my code gives error.
from datetime import datetime
datetime_object = datetime.strptime('1 June 2005','%d %m %Y')
print datetime_object
Your error is in the format you are using to strip your string. You use %m as the format specifier for month, but this expects a 0 padded integer representing the month of the year (e.g. 06 for your example). What you want to use is %B, which expects an month of the year written out fully (e.g. June in your example).
For a full explanation of the datetime format specifiers please consult the documentation, and if you have any other issues please check there first.
Here is what you should be doing:
from datetime import datetime
datetime_object = datetime.strptime('1 June 2005','%d %B %Y')
s = datetime_object.strftime("%d/%m/%y")
print(s)
Output:
>>> 01/06/05
You see your strptime requires two parameters.
strptime(string[, format])
And the string will be converted to a datetime object according to a format you specify.
There are various formats
%a - abbreviated weekday name
%A - full weekday name
%b - abbreviated month name
%B - full month name
%c - preferred date and time representation
%C - century number (the year divided by 100, range 00 to 99)
%d - day of the month (01 to 31)
%D - same as %m/%d/%y
%e - day of the month (1 to 31)
%g - like %G, but without the century
%G - 4-digit year corresponding to the ISO week number (see %V).
%h - same as %b
%H - hour, using a 24-hour clock (00 to 23)
The above are some examples. Take a look here for formats
Take a goood look at these two!
%b - abbreviated month name
%B - full month name
It should be in a similar pattern to the string you provide. Confusing take a look at these examples.
>>> datetime.strptime('1 jul 2009','%d %b %Y')
datetime.datetime(2009, 7, 1, 0, 0)
>>> datetime.strptime('1 Jul 2009','%d %b %Y')
datetime.datetime(2009, 7, 1, 0, 0)
>>> datetime.strptime('jul 21 1996','%b %d %Y')
datetime.datetime(1996, 7, 21, 0, 0)
As you can see based on the format the string is turned into a datetime object. Now take a look!
>>> datetime.strptime('1 July 2009','%d %b %Y')
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
datetime.strptime('1 July 2009','%d %b %Y')
File "/usr/lib/python3.5/_strptime.py", line 510, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.5/_strptime.py", line 343, in _strptime
(data_string, format))
ValueError: time data '1 July 2009' does not match format '%d %b %Y'
Why error because jun or Jun (short form) stands for %b. When you supply a June it gets confused. Now what to do? Changed the format.
>>> datetime.strptime('1 July 2009','%d %B %Y')
datetime.datetime(2009, 7, 1, 0, 0)
Simple now converting the datetime object is simple enough.
>>> s = datetime.strptime('1 July 2009','%d %B %Y')
>>> s.strftime('%d/%m/%Y')
'01/07/2009
Again the %m is the format for displaying it in months (numbers) read more about them.
The placeholder for "Month as locale’s full name." would be %B not %m:
>>> from datetime import datetime
>>> datetime_object = datetime.strptime('1 June 2005','%d %B %Y')
>>> print(datetime_object)
2005-06-01 00:00:00
>>> print(datetime_object.strftime("%d/%m/%Y"))
01/06/2005
This should work:
from datetime import datetime
print(datetime.strptime('1 June 2005', '%d %B %Y').strftime('%d/%m/%Y'))
print(datetime.strptime('23 July 1914', '%d %B %Y').strftime('%d/%m/%Y'))
For more info you can read about strftime-strptime-behavior
%d means "Day of the month as a zero-padded decimal number."
%m means "Month as a zero-padded decimal number."
Neither day or month are supplied what you tell it to expect. What you need it %B for month (only if your locale is en_US), and %-d for day.
I am trying to convert a date and time string such as "Mar 15, 2016 10:47:15" into a Python datetime object using strptime. I believe I have the formatting correct however I still get a ValueError exception when I run the below:
>>> s = "Mar 15, 2016 10:47:15"
>>> datetime.datetime.strptime(s,"%b %m, %Y %H:%M:%S")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Mar 15, 2016 10:47:15' does not match format '%b %m, %Y %H:%M:%S'
Any ideas as to what may be wrong with my format string?
The second item in the format string (%m) refers to month. Changing it to %d will make your code work.
datetime.datetime.strptime(s,"%b %d, %Y %H:%M:%S")
Here are the relevant parts from strptime documentation:
%d Day of the month as a zero-padded decimal number. 01, 02, ..., 31
%m Month as a zero-padded decimal number. 01, 02, ..., 12
Month name is locale-specific. If you want to use english months names set for application English-based locale like en_US.
$ env LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 python
>>> import datetime
>>> s = "Mar 15, 2016 10:47:15"
>>> datetime.datetime.strptime(s,"%b %d, %Y %H:%M:%S")
datetime.datetime(2016, 3, 15, 10, 47, 15)
P.S. %m replaced with %d, which means day.
I have a date with this format
October 14, 2014 1:35PM PDT
I have this in my python script
import time
u_date = 'October 14, 2014 1:35PM PDT'
print time.strptime(u_date,"%b %d, %y %I:%M%p %Z")
I got this error as a result
ValueError: time data u'October 14, 2014 1:35PM PDT' does not match format '%b %d, %y %I:%M%p %Z'
Can anyone explain to me why is this happening? I'm new to python and any help will be appreciated.
Your format is incorrect; %b takes an abbreviated month, but you have a full month, requiring %B, and you have a full 4-digit year, so use %Y, not %y.
The time library cannot parse timezones, however, you'll have to drop the %Z part here and remove the last characters for this to work at all:
>>> time.strptime(u_date[:-4], "%B %d, %Y %I:%M%p")
time.struct_time(tm_year=2014, tm_mon=10, tm_mday=14, tm_hour=13, tm_min=35, tm_sec=0, tm_wday=1, tm_yday=287, tm_isdst=-1)
You could use the dateutil library instead to parse the full string, it'll produce a datetime.datetime object rather than a time struct:
>>> from dateutil import parser
>>> parser.parse(u_date)
datetime.datetime(2014, 10, 14, 13, 35)
In standard python, I can convert a string representation of time into datetime doing this:
date_string = u'Tue, 13 Sep 2011 02:38:59 GMT';
date_object = datetime.strptime(date_string, '%a, %d %b %Y %H:%M:%S %Z');
This works fine until I invoke the same over app engine where I get the error:
time data did not match format: data=2011-09-13 02:38:59 fmt=%a, %d %b %Y %H:%M:%S %Z
How would I convert this date string correctly so I can get a datetime representation?
Your error message indicates that you're not really passing Tue, 13 Sep 2011 02:38:59 GMT, but 2011-09-13 02:38:59. Are you sure you pass the correct parameters to strptime?
My python works just fine for the following:
datetime.strptime(u'Tue, 13 Sep 2011 02:38:59 GMT', "%a, %d %b %Y %H:%M:%S %Z")
# returns datetime.datetime(2011, 9, 13, 2, 38, 59)
This also works fine for me:
from dateutil imoprt parser as dparser
dparser.parse("Tue, 13 Sep 2011 02:38:59 GMT")
# returns datetime.datetime(2011, 9, 13, 2, 38, 59, tzinfo=tzutc())