I am trying to match time zones with empty string in strptime function. Howevr, I get the following error.
ValueError: time data 'Thu Apr 14 01:46:29 MDT 2016' does not match format '%a %b %d %H:%M:%S %Y'
This is the code I try.
import datetime
d = datetime.datetime.strptime('Thu Apr 14 01:46:29 MDT 2016', '%a %b %d %H:%M:%S %Y')
How to map time-zone in python?
time zone can be MDT, MST,etc.
To parse this specific format (similar to rfc 822 used in emails), you could use email packages:
from email.utils import parsedate_tz, mktime_tz
time_tuple = parsedate_tz('Thu Apr 14 01:46:29 MDT 2016')
posix_time = mktime_tz(time_tuple)
Note: MDT is -6 hours here (according to the rfc 822). In general, timezone abbreviations may be ambiguous.
On Python 3.3+, you could create a timezone-aware datetime directly:
from email.utils import parsedate_to_datetime
dt = parsedate_to_datetime('Thu Apr 14 01:46:29 MDT 2016')
Here's how to parse it on earlier Python versions.
Related
I have two strings. How can I convert them to UNIX timestamp (eg.: "1284101485")? (Please observe that 1284101485 is not the correct answer for this case.)
I don't care about time zones as long as it is consistent.
string_1_to_convert = 'Tue Jun 25 13:53:58 CEST 2019'
string_2_to_convert = '2019-06-25 13:53:58'
You can use dateparser
Install:
$ pip install dateparser
Sample code:
import dateparser
from time import mktime
string_1_to_convert = 'Tue Jun 25 13:53:58 CEST 2019'
string_2_to_convert = '2019-06-25 13:53:58'
datetime1 = dateparser.parse(string_1_to_convert)
datetime2 = dateparser.parse(string_2_to_convert)
unix_secs_1 = mktime(datetime1.timetuple())
unix_secs_2 = mktime(datetime2.timetuple())
print(unix_secs_1)
print(unix_secs_2)
Output:
1561492438.0
1561488838.0
The above implementation gives you a consistent response and doesn't give you an error when trying to parse CEST.
you can use .strptime to parse by a format you specify.
try this:
import datetime
string_1_to_convert = 'Tue Jun 25 13:53:58 CEST 2019'
string_2_to_convert = '2019-06-25 13:53:58'
ts1 = datetime.datetime.strptime(string_1_to_convert, "%a %b %d %H:%M:%S %Z %Y").timestamp()
ts2 = datetime.datetime.strptime(string_2_to_convert, "%Y-%m-%d %H:%M:%S").timestamp()
print(ts1)
print(ts2)
NOTICE: the CEST part might be non-portable, as strptime only knows how to parse timezones that appear in time.tzname.
Im trying to convert a string to datetime and keep getting the error: ValueError: time data 'Mon, 22 Apr 2019 17:04:38 +0200 (CEST)' does not match format '%a, %d %b %Y %H:%M:%S %z %Z'
from datetime import datetime
s = "Mon, 22 Apr 2019 17:04:38 +0200 (CEST)"
d = datetime.strptime(s, '%a, %d %b %Y %H:%M:%S %z %Z')
What am i missing?
%Z is generally used for converting into string format. In any case, it is the offset, not the name of the time zone.
The rest of your code is valid, however:
s = "Mon, 22 Apr 2019 17:04:38 +0200"
d = datetime.strptime(s, '%a, %d %b %Y %H:%M:%S %z')
datetime only comes with the ability to parse UTC and whatever local time zone is listed in time.tzname. It can't match (CEST) because it doesn't know what timezone that is (It would also be redundant because you defined the timezone using the offset +0200).
You will need to implement your own (CEST) using datetime.tzinfo or by importing an external library like pytz or pendulum in order to parse (CEST) from a string into a datetime.timezone.
Also, don't forget to include parenthesis() in your match string.
This code passes, however, I do not know what happens to 'CEST' once it is converted into the string.
from datetime import datetime
tz = 'CEST'
s = "Mon, 22 Apr 2019 17:04:38 +0200 " + tz
d = datetime.strptime(s, '%a, %d %b %Y %H:%M:%S %z ' + tz)
When I pull events start times from Facebook Graph in comes in this form:
2017-09-26T18:00:00+0300
I'd like to convert it into readable format so I use this:
readable_event_date = dateutil.parser.parse(event_date).strftime('%a, %b %d %Y %H:%M:%S')
and it comes out like this:
Tue, 26 Sep 2017 18:00:00
Which is good but it loses the offset from UTC and I'd like it in AM PM format.
Thus, I would like it like this:
Tue, 26 Sep 2017 9:00 PM
To get into 12 hours format and keep offset from UTC for printing :
from dateutil.parser import parse
event_date = '2017-09-26T18:00:0+0300'
date = parse(event_date)
offset = date.tzinfo._offset
readable_event_date = (date + offset).strftime('%a, %b %d %Y %I:%M:%S %p')
print(readable_event_date)
Output:
'Tue, Sep 26 2017 09:00:00 PM'
It seems like what you want is this time, expressed in UTC, in the format '%a, %b %d %Y %I:%M:%S %p'. Luckily, all the information you need to do this is contained in the datetime object that you parsed, you just need to convert to UTC
Python 2.6+ or Python 3.3+:
The approach you've taken using dateutil will work for Python 2.6+ or Python 3.3.+ (and also works for a greater variety of datetime string formats):
from dateutil.parser import parse
# In Python 2.7, you need to use another one
from dateutil.tz import tzutc
UTC = tzutc()
dt_str = '2017-09-26T18:00:00+0300'
dt = parse(dt_str)
dt_utc = dt.astimezone(UTC) # Convert to UTC
print(dt_utc.strftime('%a, %b %d %Y %I:%M:%S %p'))
# Tue, Sep 26 2017 03:00:00 PM
One thing I notice is that the date you've provided, as far as I can tell, represents 3PM in UTC, not 9PM (as your example states). This is one reason you should use .astimezone(UTC) rather than some other approach.
If you want to include the time zone offset information, you can also use the %z parameter on the non-converted version of the datetime object.
print(dt.strftime('%a, %b %d %Y %I:%M:%S%z %p'))
# Tue, Sep 26 2017 06:00:00+0300 PM
This %z parameter may also be useful even if you are keeping it in UTC, because then you can at least be clear that the date the user is seeing is a UTC date.
Python 3.2+ only:
Given that you know the exact format of the input string, in Python 3.2+, you can achieve this same thing without pulling in dateutil, and it will almost certainly be faster (which may or may not be a concern for you).In your case here is how to rewrite the code so that it works with just the standard library:
from datetime import datetime, timezone
UTC = timezone.utc
dt_str = '2017-09-26T18:00:00+0300'
dt = datetime.strptime(dt_str, '%Y-%m-%dT%H:%M:%S%z')
dt_utc = dt.astimezone(UTC)
print(dt_utc.strftime('%a, %b %d %Y %I:%M:%S %p'))
# Tue, Sep 26 2017 03:00:00 PM
print(dt.strftime('%a, %b %d %Y %I:%M:%S%z %p'))
# Tue, Sep 26 2017 06:00:00+0300 PM
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.
I have these date strings:
Fri Oct 7 16:00:09 CEST 2011
I want to convert them to UTC. I have tried with this implementation:
def LocalToUtc(localtime):
return datetime.strptime(localtime, "%a %m %d %H:%M:%S %Z %Y").isoformat() + 'Z'
But I get a ValueError:
ValueError: time data 'Fri Oct 7 16:00:09 CEST 2011' does not match format '%a %m %d %H:%M:%S %Z %Y'
Any ideas?
Use the parsedatetime library.
There are two problems here:
You're using "%m" instead of "%b"
The standard lib can't parse "CEST", it understands only very few time zone names.
See also here: What possible values does datetime.strptime() accept for %Z?