I have a String, Sent: Fri Sep 18 00:30:12 2009 that I want to turn into a Python date object.
I know there's a strptime() function that can be used like so:
>>> dt_str = '9/24/2010 5:03:29 PM'
>>> dt_obj = datetime.strptime(dt_str, '%m/%d/%Y %I:%M:%S %p')
>>> dt_obj
datetime.datetime(2010, 9, 24, 17, 3, 29)
Can anybody think of an easier way to accomplish this than going through a bunch of conditionals to parse out if Sep, month = 9?
To parse rfc 822-like date-time string, you could use email stdlib package:
>>> from email.utils import parsedate_to_datetime
>>> parsedate_to_datetime('Fri Sep 18 00:30:12 2009')
datetime.datetime(2009, 9, 18, 0, 30, 12)
This is Python 3 code, see Python 2.6+ compatible code.
You could also provide the explicit format string:
>>> from datetime import datetime
>>> datetime.strptime('Fri Sep 18 00:30:12 2009', '%a %b %d %H:%M:%S %Y')
datetime.datetime(2009, 9, 18, 0, 30, 12)
See the table with the format codes.
Use the python-dateutil library!
First: pip install python-dateutil into your virtual-env if you have one then you can run the following code:
from dateutil import parser
s = u'Sent: Fri Sep 18 00:30:12 2009'
date = parser.parse(s.split(':', 1)[-1])
Related
I need to
parse a localized string to a datetime object,
use a datetime object to generate a localized string.
The problem is that the default locale ("de_DE") does not match the localized string ("en_US").
What options are there to implement the described conversions?
Please note that I have not studied all available libraries and just want to provide a starting point for others to solve their problems.
I will use the following localized string during all examples:
dt_str = "Thu 3 Apr 2014 13:19:52" # en_US
1. Methods of 'datetime.datetime'
This is the simplest approach, but it becomes unwieldy if you use locales other than the default locale.
Information about the syntax can be found here.
import datetime
dt = datetime.datetime.strptime(dt_str,
"%a %d %b %Y %H:%M:%S")
# datetime.datetime(2014, 4, 3, 13, 19, 52)
s = dt.strftime("%a %-d %b %Y %H:%M:%S")
# 'Thu 3 Apr 2014 13:19:52'
If you like to parse or format other locales, you have to change the global locale, which could result in undesired side effects. (I do not recommend this approach.)
import datetime
import locale
locale.setlocale(locale.LC_TIME, "de_DE.UTF-8")
dt = datetime.datetime.strptime("Do 3 Apr 2014 13:19:52",
"%a %d %b %Y %H:%M:%S")
# datetime.datetime(2014, 4, 3, 13, 19, 52)
s = dt.strftime("%a %-d %b %Y %H:%M:%S")
# 'Do 3 Apr 2014 13:19:52'
2. The python library 'arrow'
arrow allows you to pass a locale (otherwise it uses "en_US").
import arrow # installed via pip
import datetime
### localized string -> datetime
a_dt = arrow.get(dt_str,
"ddd D MMM YYYY H:mm:ss",
locale="en_US") # "en_US" is also the default, so this is just for clarification
dt = a_dt.datetime
# datetime.datetime(2014, 4, 3, 13, 19, 52, tzinfo=tzutc())
### datetime -> localized string
a_s = arrow.get(datetime.datetime(2014, 5, 17, 14, 0, 0))
s = a_s.format("ddd D MMM YYYY H:mm:ss",
locale="en_US") # "en_US" is also the default, so this is just for clarification
# 'Sat 17 May 2014 14:00:00'
This is especially useful if the desired locale differs from the default locale.
3. The python library 'babel' (mainly for formatting)
The strength of babel is the formatting (Unfortunately, it seems that it can not parse any pattern. Only the format "short" seems reliable.)
import babel.dates # 'babel' installed via pip
import datetime
dt = datetime.datetime(2014, 4, 3, 13, 19, 52)
# parsing is the problem with babel, therefore I created the datetime object directly.
s = babel.dates.format_datetime(dt,
"EEE d MMM yyyy H:mm:ss",
locale="en_US")
# 'Thu 3 Apr 2014 13:19:52'
4. The python library 'dateparser' (only parsing)
dateparser is very powerful. It is able to lookup dates in longer texts and does support non-Gregorian calendar systems, just to name a few features.
import dateparser # installed via pip
dt = dateparser.parse(dt_str,
date_formats=["%a %d %b %Y %H:%M:%S"],
languages=["en"])
# datetime.datetime(2014, 4, 3, 13, 19, 52)
5. Last but not least
The following noteworthy python libraries have great features, but unfortunately I could not use them for this specific problem (or did not know how to use them properly).
maya
delorean
pendulum
I have a string like this
dateStr = "Wed Mar 15 12:50:52 GMT+05:30 2017"
which is IST time.
Is there any way to read the dateStr as per the specified timezone within the dateStr
i.e. GMT+05:30.
So that I can make datetime object directly.
I have tried to parse it using format
format = "%a %b %d %H:%M:%S %Z%z %Y"
But it gives me error of format does not match.
Can you try this?
>>> dateStr = "Wed Mar 15 12:50:52 GMT+05:30 2017"
>>> from dateutil.parser import parse
>>> parse(dateStr)
datetime.datetime(2017, 3, 15, 12, 50, 52, tzinfo=tzoffset(None, -19800))
I have dates in the following format that are used to name zip files:
Apr 15 2014 16:21:16 UTC
I would like to convert that to UTC numbers using Python. Does python recognize the 3-character month?
Use:
import datetime
datetime.datetime.strptime(yourstring, '%b %d %Y %H:%M:%S UTC')
%b is the abbreviated month name. By default, Python uses the C (English) locale, regardless of environment variables used.
Demo:
>>> import datetime
>>> yourstring = 'Apr 15 2014 16:21:16 UTC'
>>> datetime.datetime.strptime(yourstring, '%b %d %Y %H:%M:%S UTC')
datetime.datetime(2014, 4, 15, 16, 21, 16)
The value is timezone neutral, which for UTC timestamps is fine, provided you don't mix local objects into the mix (e.g. stick to datetime.datetime.utcnow() and similar methods).
An easier way is to use dateutil:
>>> from dateutil import parser
>>> parser.parse("Apr 15 2014 16:21:16 UTC")
datetime.datetime(2014, 4, 15, 16, 21, 16, tzinfo=tzutc())
Timezone is handled, and it supports other common datetime formats as well.
This question already has answers here:
Python time to age
(6 answers)
Closed 8 years ago.
Following on from my previous question, Python time to age, I have now come across a problem regarding the timezone, and it turns out that it's not always going to be "+0200". So when strptime tries to parse it as such, it throws up an exception.
I thought about just chopping off the +0200 with [:-6] or whatever, but is there a real way to do this with strptime?
I am using Python 2.5.2 if it matters.
>>> from datetime import datetime
>>> fmt = "%a, %d %b %Y %H:%M:%S +0200"
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200", fmt)
datetime.datetime(2008, 7, 22, 8, 17, 41)
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0300", fmt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.5/_strptime.py", line 330, in strptime
(data_string, format))
ValueError: time data did not match format: data=Tue, 22 Jul 2008 08:17:41 +0300 fmt=%a, %d %b %Y %H:%M:%S +0200
is there a real way to do this with strptime?
No, but since your format appears to be an RFC822-family date, you can read it much more easily using the email library instead:
>>> import email.utils
>>> email.utils.parsedate_tz('Tue, 22 Jul 2008 08:17:41 +0200')
(2008, 7, 22, 8, 17, 41, 0, 1, 0, 7200)
(7200 = timezone offset from UTC in seconds)
New in version 2.6.
For a naive object, the %z and %Z
format codes are replaced by empty
strings.
It looks like this is implemented only in >= 2.6, and I think you have to manually parse it.
I can't see another solution than to remove the time zone data:
from datetime import timedelta,datetime
try:
offset = int("Tue, 22 Jul 2008 08:17:41 +0300"[-5:])
except:
print "Error"
delta = timedelta(hours = offset / 100)
fmt = "%a, %d %b %Y %H:%M:%S"
time = datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200"[:-6], fmt)
time -= delta
You can use the dateutil library which is very useful:
from datetime import datetime
from dateutil.parser import parse
dt = parse("Tue, 22 Jul 2008 08:17:41 +0200")
## datetime.datetime(2008, 7, 22, 8, 17, 41, tzinfo=tzoffset(None, 7200)) <- dt
print dt
2008-07-22 08:17:41+02:00
As far as I know, strptime() doesn't recognize numeric time zone codes. If you know that the string is always going to end with a time zone specification of that form (+ or - followed by 4 digits), just chopping it off and parsing it manually seems like a perfectly reasonable thing to do.
It seems that %Z corresponds to time zone names, not offsets.
For example, given:
>>> format = '%a, %d %b %Y %H:%M:%S %Z'
I can parse:
>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 GMT', format)
datetime.datetime(2008, 7, 22, 8, 17, 41)
Although it seems that it doesn't do anything with the time zone, merely observing that it exists and is valid:
>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 NZDT', format)
datetime.datetime(2008, 7, 22, 8, 17, 41)
I suppose if you wished, you could locate a mapping of offsets to names, convert your input, and then parse it. It might be simpler to just truncate your input, though.
This question already has answers here:
Python time to age
(6 answers)
Closed 8 years ago.
Following on from my previous question, Python time to age, I have now come across a problem regarding the timezone, and it turns out that it's not always going to be "+0200". So when strptime tries to parse it as such, it throws up an exception.
I thought about just chopping off the +0200 with [:-6] or whatever, but is there a real way to do this with strptime?
I am using Python 2.5.2 if it matters.
>>> from datetime import datetime
>>> fmt = "%a, %d %b %Y %H:%M:%S +0200"
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200", fmt)
datetime.datetime(2008, 7, 22, 8, 17, 41)
>>> datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0300", fmt)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.5/_strptime.py", line 330, in strptime
(data_string, format))
ValueError: time data did not match format: data=Tue, 22 Jul 2008 08:17:41 +0300 fmt=%a, %d %b %Y %H:%M:%S +0200
is there a real way to do this with strptime?
No, but since your format appears to be an RFC822-family date, you can read it much more easily using the email library instead:
>>> import email.utils
>>> email.utils.parsedate_tz('Tue, 22 Jul 2008 08:17:41 +0200')
(2008, 7, 22, 8, 17, 41, 0, 1, 0, 7200)
(7200 = timezone offset from UTC in seconds)
New in version 2.6.
For a naive object, the %z and %Z
format codes are replaced by empty
strings.
It looks like this is implemented only in >= 2.6, and I think you have to manually parse it.
I can't see another solution than to remove the time zone data:
from datetime import timedelta,datetime
try:
offset = int("Tue, 22 Jul 2008 08:17:41 +0300"[-5:])
except:
print "Error"
delta = timedelta(hours = offset / 100)
fmt = "%a, %d %b %Y %H:%M:%S"
time = datetime.strptime("Tue, 22 Jul 2008 08:17:41 +0200"[:-6], fmt)
time -= delta
You can use the dateutil library which is very useful:
from datetime import datetime
from dateutil.parser import parse
dt = parse("Tue, 22 Jul 2008 08:17:41 +0200")
## datetime.datetime(2008, 7, 22, 8, 17, 41, tzinfo=tzoffset(None, 7200)) <- dt
print dt
2008-07-22 08:17:41+02:00
As far as I know, strptime() doesn't recognize numeric time zone codes. If you know that the string is always going to end with a time zone specification of that form (+ or - followed by 4 digits), just chopping it off and parsing it manually seems like a perfectly reasonable thing to do.
It seems that %Z corresponds to time zone names, not offsets.
For example, given:
>>> format = '%a, %d %b %Y %H:%M:%S %Z'
I can parse:
>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 GMT', format)
datetime.datetime(2008, 7, 22, 8, 17, 41)
Although it seems that it doesn't do anything with the time zone, merely observing that it exists and is valid:
>>> datetime.datetime.strptime('Tue, 22 Jul 2008 08:17:41 NZDT', format)
datetime.datetime(2008, 7, 22, 8, 17, 41)
I suppose if you wished, you could locate a mapping of offsets to names, convert your input, and then parse it. It might be simpler to just truncate your input, though.