This question already has answers here:
Parse hours without leading zeroes by strptime in Python
(3 answers)
Closed 4 years ago.
For some reason python is not parsing my date properly but I looked at the strftime/strptime behavior and it looks to be right
import time
d = 'May 17, 2018 3:10 AM PDT'
time.mktime(time.strptime(d, "%B %d, %Y %I:%M %p %Z"))
If I do:
time.strftime("%B %d, %Y %I:%M %p %Z")
I get May 18, 2018 02:47 PM EDT, which looks to be the exact same format except for the leading 0 but strptime should be able to parse leading 0s.
What am I doing wrong in parsing this date?
Edit: Found out its the timezone but not sure why:
time.mktime(time.strptime("May 17, 2018 3:10 AM UTC", "%B %d, %Y %I:%M %p %Z"))
returns a value
time.mktime(time.strptime("May 17, 2018 3:10 AM PDT", "%B %d, %Y %I:%M %p %Z"))
returns ValueError
Python date handling has always been a little light in the timezone handling department (it's a complicated problem). You can implement your own derived tzinfo class from the abstract base class provided in the standard library if you only have a small subset of them that need to be handled—I've done it before and it's not too hard—or you can use something like the third-party dateutil module recommended in the documentation at the end of the tzinfo section which handles a much larger number of them.
Anyway, you can get dateutil from here or you can simply install it from an OS command line with pip install py-dateutil.
from dateutil import parser
t = parser.parse('May 17, 2018 3:10 AM PDT')
print('t: {!r}'.format(t)) # -> t: datetime.datetime(2018, 5, 17, 3, 10)
Related
I'm having trouble converting a string to data format. I'm using the time module to convert a string to the YYYY-MM-DD format. The code below is what I've tried but I get the following error.
sre_constants.error: redefinition of group name 'Y' as group 5; was group 3
Here is the code
import time
review_date = "April 18, 2018"
review_date = time.strptime(review_date, '%m %d %Y %I:%Y%m%d')
Firstly, the error is because you're using %Y, %m, and %d twice in your time.strptime() call.
Secondly, you're using the wrong format. The format you pass to strptime() has to match the format of the date / time string you pass, which in this case is: %B %d, %Y.
This is a good reference on the different format types.
I normally use datetime for this:
from datetime import datetime
review_date = "April 18, 2018"
review_date = datetime.strptime(review_date, '%B %d, %Y').strftime('%Y-%m-%d')
This code returns review_date = '2018-04-18'. See https://docs.python.org/3/library/datetime.html
The date format for April is %B. strptime() converts to a datetime object, .strftime() converts the datetime object to a string.
time.strptime() is for parsing strings into date/time structures. It takes two arguments, the string to be parsed and another string describing the format of the string to be parsed.
Try this:
time.strptime("April 18, 2018", "%B %d, %Y")
... and notice that "%B %d, %Y" is:
Full locale name of the month ("April")
[Space]
Date of the month (18)
[Comma]
[Space]
Four digit year (2018)
The format string specification that you provided bears no resemblance to the formatting of your date string.
These "magic" formatting codes are enumerated in the documentation for time.strftime()
review_date = time.strptime(review_date, '%B %d, %Y')
import time
review_date = "April 18, 2018"
review_date = time.strptime(review_date, '%B %d, %Y')
That's what you should have
I'm trying to convert a string into a date format, to be later stored into an SQLite database. Below is the code line at which I'm getting an error.
date_object = datetime.strptime(date, '%b %d, %Y %H:%M %Z')
And this is the error:
File "00Basic.py", line 20, in spider
date_object = datetime.strptime(date, '%b %d, %Y %H:%M %Z') File "C:\Python27\lib\_strptime.py", line 332, in _strptime
(data_string, format)) ValueError: time data 'Aug 19, 2016 08:13 IST' does not match format '%b %d, %Y %H %M %Z'
Question 1: How do I resolve this error?
Question 2: Is this the right approach for preparing to store the date in SQLite later?
Please Note: Very new to programming.
You could use pytz for the timezone conversion as shown:
from datetime import datetime
from pytz import timezone
s = "Aug 19, 2016 08:13 IST".replace('IST', '')
print(timezone('Asia/Calcutta').localize(datetime.strptime(s.rstrip(), '%b %d, %Y %H:%M')))
#2016-08-19 08:13:00+05:30
#<class 'datetime.datetime'>
I would suggest you to use dateutil incase you are handling multiple timezones of string.
The problem is located in the %Z (Time zone) part of the format.
As the documentation explains
%Z Time zone name (empty string if the object is naive). (empty), UTC, EST, CST
It looks like only UTC,EST and CST are valid. (Or it just doesn't recognize IST)
In order to fix this, you could use the %z parameter that accepts any UTC offset, like so:
struct_time = time.strptime("Aug 19, 2016 08:13 +0530", '%b %d, %Y %H:%M %z')
Update: Although this works fine in Python +3.2 it raises an exception when it's run with Python2
I have date as
In [1]: a = "Sun 10 May 2015 13:34:36 -0700"
When I try to convert it using strptime, its giving error.
In [3]: datetime.strptime(a, "%a %d %b %Y %H:%M:%S %Z"
...: )
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-973ef1c6daca> in <module>()
----> 1 datetime.strptime(a, "%a %d %b %Y %H:%M:%S %Z"
2 )
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
323 if not found:
324 raise ValueError("time data %r does not match format %r" %
--> 325 (data_string, format))
326 if len(data_string) != found.end():
327 raise ValueError("unconverted data remains: %s" %
ValueError: time data 'Sun 10 May 2015 13:34:36 -0700' does not match format '%a %d %b %Y %H:%M:%S %Z'
In [6]: datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-6-e4870e34edda> in <module>()
----> 1 datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
315 del err
316 raise ValueError("'%s' is a bad directive in format '%s'" %
--> 317 (bad_directive, format))
318 # IndexError only occurs when the format string is "%"
319 except IndexError:
ValueError: 'z' is a bad directive in format '%a %d %b %Y %H:%M:%S %z'
As per doc, correct format is %z, but I might missing some part.
From the link you provided for the python doc, I found that you are using Python 2.7
It looks as if strptime doesn't always support %z. Python appears to just call the C function, and strptime doesn't support %z on your platform.
Note: from Python 3.2 onwards it will always work.
I am using Python 3.4 in which it is working fine
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
Update using dateutil
$ pip install python-dateutil
from dateutil import parser
parsed_date = parser.parse(date)
>>> parsed_date
datetime.datetime(2015, 3, 14, 18, 43, 19)
Your format string is correct and works fine in Python 3.3:
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
datetime.datetime(2015, 5, 10, 13, 34, 36, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))
It gives the error in Python 2.7 indeed.
Unlike strftime(), which is implemented by calling the libc function, strptime() is implemented in the Python library. Here you can see that the version used in Python 2.7 doesn’t support the z format. On the other hand here is the version from Python 3.3, which supports that (I think this was added around 3.2).
So, basically, you have two options:
Using some external library that is able to handle z.
Implementing it yourself (e.g. by stripping the timezone from the string, feeding the first part to strptime() and parsing the second one manually). Looking at how this is done in the Python library might be helpful.
I tried to parse this to return an “aware” object, but it is somewhat complicated.
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> time, tz = a.rsplit(' ', 1)
>>> d = datetime.strptime(time, '%a %d %b %Y %H:%M:%S')
datetime.datetime(2015, 5, 10, 13, 34, 36)
Now I have to call d.replace(tzinfo=…tz…) to replace the timezone, but the problem is that I can’t get an instance of tzinfo because just knowing the offset from UTC is not enough to identify a timezone.
In Python 3.2 there is a special timezone class that is a subclass of tzinfo representing a “fake” timezone defined by just its offset. So there are two ways to proceed:
Backport (basically, copy and paste) the timezone class from Python 3 and use it in your parser.
Return a “naive” object:
>>> d + timedelta(hours=int(tz[1:]) * (1 if tz.startswith('-') else -1))
datetime.datetime(2015, 6, 8, 17, 34, 36)
You can parse your input format using only stdlib even in Python 2.7:
>>> from datetime import datetime
>>> from email.utils import mktime_tz, parsedate_tz
>>> mktime_tz(parsedate_tz("Sun 10 May 2015 13:34:36 -0700"))
1431290076
>>> datetime.utcfromtimestamp(_)
datetime.datetime(2015, 5, 10, 20, 34, 36)
The result is a naive datetime object that represents time in UTC.
See other solutions and the way to get an aware datetime object in Python: parsing date with timezone from an email.
This question already has answers here:
Python date string to date object
(9 answers)
Closed 8 years ago.
I have a unicode string u'May 12, 2014 8:00:40 PM' and I want to convert it into a date time object but I dont want time stamp, only date.
output should be 2014/5/12 or 2014/05/12
I tried to use strptime but it didn't help me. may be I'm missing something else?
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
326 if len(data_string) != found.end():
327 raise ValueError("unconverted data remains: %s" %
--> 328 data_string[found.end():])
329
330 year = None
ValueError: unconverted data remains: 1:33PM
I've already seen these threads
Converting string into datetime
convert string to date type python
Convert string into Date type on Python
datetime.datetime.strptime() expects to parse all of the input string. If you pass in u'May 12, 2014 8:00:40 PM', you'll need to account for all characters.
Either split off the time portion, or parse the time portion as well, then ignore that part by calling .date() on the resulting datetime.datetime() object.
It's easier to just include the time:
dateobj = datetime.datetime.strptime(inputstring, '%B %d, %Y %I:%M:%S %p').date()
This gives you a datetime.date() object for just the date portion of the string.
Cutting of the time portion can be done with a str.rsplit() call, limited to 2 splits:
dateobj = datetime.datetime.strptime(inputstring.rsplit(None, 2)[0], '%B %d, %Y').date()
I've called .date() here as well.
Demo:
>>> import datetime
>>> inputstring = u'May 12, 2014 8:00:40 PM'
>>> datetime.datetime.strptime(inputstring, '%B %d, %Y %I:%M:%S %p').date()
datetime.date(2014, 5, 12)
>>> datetime.datetime.strptime(inputstring.rsplit(None, 2)[0], '%B %d, %Y').date()
datetime.date(2014, 5, 12)
I am need to convert a date in below format into different format for displaying purpose. But before that I am trying to convert the date in string to time object, but not able to do so.
>>> time.strptime("Thu Mar 13 23:15:13 2014 EDT", '%a %b %d %H:%M:%S %Y %Z')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "/usr/lib64/python2.4/_strptime.py", line 293, in strptime
raise ValueError("time data did not match format: data=%s fmt=%s" %
ValueError: time data did not match format: data=Thu Mar 13 23:15:13 2014 EDT fmt=%a %b %d %H:%M:%S %Y %Z
Did a trial and error and it's the '%Z' causing the issue, below works fine (just %Z is removed)
>>> time.strptime("Thu Mar 13 23:15:13 2014", '%a %b %d %H:%M:%S %Y')
(2014, 3, 13, 23, 15, 13, 3, 72, -1)
Python wiki (https://docs.python.org/2/library/time.html) says timezone specifier is %Z, then what is the issue here. Please help me find.
Python version: 2.4.3
From the Python documentation. https://docs.python.org/2/library/time.html#time.strptime
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).
Which basically says that time.strptime() will only recognize timezones that are listed in time.tzname
Hope this helps
%z will only work for numeric timezone in python 3.x, here is a fix for python 2.x:
Instead of using:
datetime.strptime(t,'%Y-%m-%dT%H:%M %z')
use the timedelta to account for the timezone, like this:
from datetime import datetime,timedelta
def dt_parse(t):
ret = datetime.strptime(t[0:16],'%Y-%m-%dT%H:%M')
if t[18]=='+':
ret+=timedelta(hours=int(t[19:22]),minutes=int(t[23:]))
elif t[18]=='-':
ret-=timedelta(hours=int(t[19:22]),minutes=int(t[23:]))
return ret