Cannot parse the date in Python - python

I need to parse date and time. Here is what I've got:
import time
a = time.strptime('Apr 28 2013 23:01', "%b %d %y %H:%M")
print a
But it gives me
Traceback (most recent call last):
File "/home/aaa/Documents/python_test.py", line 17, in <module>
a = time.strptime('Apr 28 2013 23:01', "%b %d %y %H:%M")
File "/usr/lib/python2.7/_strptime.py", line 467, in _strptime_time
return _strptime(data_string, format)[0]
File "/usr/lib/python2.7/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Apr 28 2013 23:01' does not match format '%b %d %y %H:%M'
What am I doing wrong?

%y should be %Y for a 4 digit year...
From the docs:
%y Year without century as a decimal number [00,99].
%Y Year with century as a decimal number.

You can
import time
a = time.strptime('Apr 28 2013 23:01', "%b %d %Y %H:%M")
print time.strftime("%d/%m/%Y",a)
with Y. It is followed by a conversion line of code, and gives result
28/04/2013

Jon's answer is of course correct, but as you noticed these things can be difficult to find.
As a general suggestion for debugging strptime problems I recommend printing out a known datetime using the format string you use for parsing:
from datetime import datetime
d = datetime(2013, 4, 28, 23, 1)
print d.strftime("%b %d %y %H:%M")
print 'Apr 28 2013 23:01'
A visual comparison of the output lines:
Apr 28 13 23:01
Apr 28 2013 23:01
quickly finds the problem and also works when your format string is correct, but you are working with a different locale (e.g. in Spanish where it would expect 'Abr' instead of 'Apr')

Related

Convert date string (from gmail) to timestamp | Python

I want to save the received date of emails from a Gmail account into a time-series database.
The problem is that I cannot convert the string that I got from the email to timestamp.
I tried this:
from datetime import datetime
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (PDT)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z %Z')
print(date1_obj)
But got this error:
Traceback (most recent call last):
File "/format_date.py", line 11, in <module>
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z %Z')
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 577, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
File "/usr/local/Cellar/python/3.7.7/Frameworks/Python.framework/Versions/3.7/lib/python3.7/_strptime.py", line 359, in _strptime
(data_string, format))
ValueError: time data 'Thu, 28 May 2020 08:15:58 -0700 (PDT)' does not match format '%a, %d %b %Y %H:%M:%S %z %Z'
Tried with or without parenthesis wrapping Timezone.
Read a lot, but nothing about how to deal with date strings containing "(PDT)" or any other timezones. It's very important to get the right date... If I run the same code without "(PDT)", got an incorrect time (because of my local time).
I know I can use string methods to manipulate it and convert to a right datetime, but I feel like this would be flexible.
Sorry for my terrible English.
Thank you!
you could use dateutil's parser to parse the string, automatically inferring the format:
import dateutil
s = 'Thu, 28 May 2020 08:15:58 -0700 (PDT)'
dt = dateutil.parser.parse(s)
# datetime.datetime(2020, 5, 28, 8, 15, 58, tzinfo=tzoffset('PDT', -25200))
dt.utcoffset().total_seconds()
# -25200.0
Note that although the timezone is given a name ("PDT"), it is only a UTC offset of 25200 s. In many cases that is sufficient, at least to convert to UTC.
If you need the specific timezone (e.g. to account for DST transitions etc.), you can use a mapping dict that you supply to dateutil.parser.parse as tzinfos:
tzmap = {'PDT': dateutil.tz.gettz('US/Pacific'),
'PST': dateutil.tz.gettz('US/Pacific')}
dt = dateutil.parser.parse(s, tzinfos=tzmap)
# datetime.datetime(2020, 5, 28, 8, 15, 58, tzinfo=tzfile('US/Pacific'))
dt.utcoffset().total_seconds()
# -25200.0
Close, you forgot to put the bracket around the last entry.
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
Well, after all your answers, which were very helpful, I finally solved.
This is how:
>>> from email.utils import parsedate_tz, mktime_tz
>>> date = 'Thu, 28 May 2020 08:15:58 -0700 (PST)'
>>> timestamp = mktime_tz(parsedate_tz(date))
>>> timestamp
1590678958
>>>
I checked that timestamp, and stands to 12:15:58 local time, what it's exactly what I was looking for.
Thank you very much to everybody who took a minute to answer.
If it does not work even if you enclose %Z in brackets then the problem lies within the %Z directive
https://docs.python.org/3/library/time.html
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).
In example the following results in a ValueError for me (in Europe)
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (PST)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
print(date1_obj)
While with GMT it the output is 2020-05-28 08:15:58-07:00
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (GMT)'
date1_obj = datetime.strptime(date1, '%a, %d %b %Y %H:%M:%S %z (%Z)')
print(date1_obj)
Based on your comment under this answer you could split the string if the Timezone bit is not important:
date1 = 'Thu, 28 May 2020 08:15:58 -0700 (GMT)'
date1_obj = datetime.strptime(date1.split(" (")[0], '%a, %d %b %Y %H:%M:%S %z')

Python : Converting string to datetime [duplicate]

I was trying to convert a string to a datetime object.
The string I got from a news feed is in the following format:
"Thu, 16 Oct 2014 01:16:17 EDT"
I tried using datetime.strptime() to convert it.
i.e.,
datetime.strptime('Thu, 16 Oct 2014 01:16:17 EDT','%a, %d %b %Y %H:%M:%S %Z')
And got the following error:
Traceback (most recent call last):
File "", line 1, in
datetime.strptime('Thu, 16 Oct 2014 01:16:17 EDT','%a, %d %b %Y %H:%M:%S %Z')
File "C:\Anaconda\lib_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data 'Thu, 16 Oct 2014 01:16:17 EDT' does not match
format '%a, %d %b %Y %H:%M:%S %Z'
However, if I tried the string without "EDT", it worked.
i.e.,
datetime.strptime('Thu, 16 Oct 2014 01:16:17','%a, %d %b %Y %H:%M:%S')
Does anyone know how to parse that "EDT" part?
To parse the date in RFC 2822 format, you could use email package:
from datetime import datetime, timedelta
from email.utils import parsedate_tz, mktime_tz
timestamp = mktime_tz(parsedate_tz("Thu, 16 Oct 2014 01:16:17 EDT"))
# -> 1413436577
utc_dt = datetime(1970, 1, 1) + timedelta(seconds=timestamp)
# -> datetime.datetime(2014, 10, 16, 5, 16, 17)
Note: parsedate_tz() assumes that EDT corresponds to -0400 UTC offset but it might be incorrect in Australia where EDT is +1100 (AEDT is used by pytz in this case) i.e., a timezone abbreviation may be ambiguous. See Parsing date/time string with timezone abbreviated name in Python?
Related Python bug: %Z in strptime doesn't match EST and others.
If your computer uses POSIX timestamps (likely), and you are sure the input date is within an acceptable range for your system (not too far into the future/past), and you don't need to preserve the microsecond precision then you could use datetime.utcfromtimestamp:
from datetime import datetime
from email.utils import parsedate_tz, mktime_tz
timestamp = mktime_tz(parsedate_tz("Thu, 16 Oct 2014 01:16:17 EDT"))
# -> 1413436577
utc_dt = datetime.utcfromtimestamp(timestamp)
# -> datetime.datetime(2014, 10, 16, 5, 16, 17)
The email.utils.parsedate_tz() solution is good for 3-letter timezones but it does not work for 4 letters such as AEDT or CEST. If you need a mix, the answer under Parsing date/time string with timezone abbreviated name in Python? works for both with the most commonly used time zones.

python change Jun to June

I take the tomorrows date like this
tomorrow = datetime.date.today() + datetime.timedelta(days=1)
self.FirstDateString = str(tomorrow.strftime("%d %b %Y"))
and the result is 11 Jun 2014
I parse it like this:
datetime.strptime('11 Jun 2014', "%d %B %Y").date()
I got this error:
ValueError: time data '11 Jun 2014' does not match format '%d %B %Y'
but when I change Jun to June, it works.
So, how can I tell the tomorrow = datetime.date.today() + datetime.timedelta(days=1) to give me June instead of Jun
in my case I will have both Jun and June so I would prefer to change Jun to June to make everything works
I think I understand the issue. You don't need to convert the datetime object to a string first:
import datetime
today = datetime.datetime.today()
print(datetime.datetime.strftime(today, '%d %b %Y'))
print(datetime.datetime.strftime(today, '%d %B %Y'))
This will give you:
10 Jun 2014
10 June 2014
Now, if your problem is that you have some strings and want to convert them, but some have Jun and others June, you don't have a choice but to try it one way, and if it doesn't work, try it the other way:
try:
obj = datetime.datetime.strptime(some_string, '%d %b %Y')
except ValueError:
# It didn't work with %b, try with %B
try:
obj = datetime.datetime.strptime(some_string, '%d %B %Y')
except ValueError:
# Its not Jun or June, eeek!
raise ValueError("Date format doesn't match!")
print('The date is: {0.day} {0.month} {0.year}'.format(obj))
You need to use the %b format code for abbreviated month names:
>>> from datetime import datetime
>>>
>>> datetime.strptime('11 Jun 2014', "%d %B %Y").date()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python33\lib\_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "C:\Python33\lib\_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '11 Jun 2014' does not match format '%d %B %Y'
>>>
>>> datetime.strptime('11 Jun 2014', "%d %b %Y").date()
datetime.date(2014, 6, 11)
>>>

Transforming a string to valid date time object that contain zone name

I have the following string
date = "Thu May 08 2014 12:06:43 GMT+0300 (EEST)"
How can I turn it in to a valid python datetime object using stptime?
I did this
datePy = datetime.strptime(date, "%a, %d %b %Y %H:%M:%S (%Z)")
but didn't work. The traceback
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 'Thu May 08 2014 12:06:43 GMT+0300 (EEST)' does not match format '%a, %d %b %Y %H:%M:%S (%Z)'
For some background details I get the date string from javascript Date.toString() function send it to my django back end and want to turn it to python datetime object that is naive.
You aren't using the correct formatting (which is quite clear from the error). For example, you have a , after the %a which isn't there in your string and %d (Day of the month as a zero-padded decimal number.) instead of %B (Month as locale’s full name). Try:
datePy = datetime.strptime(date, "%a %B %d %Y %H:%M:%S (%Z)")

Converting string with UTC offset to a datetime object [duplicate]

This question already has answers here:
Parsing date with timezone from an email?
(8 answers)
Closed 8 years ago.
Given this string: "Fri, 09 Apr 2010 14:10:50 +0000" how does one convert it to a datetime object?
After doing some reading I feel like this should work, but it doesn't...
>>> from datetime import datetime
>>>
>>> str = 'Fri, 09 Apr 2010 14:10:50 +0000'
>>> fmt = '%a, %d %b %Y %H:%M:%S %z'
>>> datetime.strptime(str, fmt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/_strptime.py", line 317, in _strptime
(bad_directive, format))
ValueError: 'z' is a bad directive in format '%a, %d %b %Y %H:%M:%S %z'
It should be noted that this works without a problem:
>>> from datetime import datetime
>>>
>>> str = 'Fri, 09 Apr 2010 14:10:50'
>>> fmt = '%a, %d %b %Y %H:%M:%S'
>>> datetime.strptime(str, fmt)
datetime.datetime(2010, 4, 9, 14, 10, 50)
But I'm stuck with "Fri, 09 Apr 2010 14:10:50 +0000". I would prefer to convert exactly that without changing (or slicing) it in any way.
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.

Categories