I have the following string which I am trying to convert to a datetime in python
From django template I am getting the following date format:
July 1, 2013, midnight
I am trying to convert the string above into a date time format
date_object = datetime.strptime(x, '%B %d, %Y, %I:%M %p')
It throws a format error
time data 'July 1, 2013, midnight' does not match format '%B %d, %Y, %I:%M %p'
Your best shot is probably the parsedatetime module.
Here's your example:
>>> import parsedatetime
>>> cal = parsedatetime.Calendar()
>>> cal.parse('July 1, 2013, midnight')
((2013, 7, 1, 0, 0, 0, 0, 245, 0), 3)
cal.parse() returns a tuple of two items. The first is the modified parsedatetime.Calendar object, the second is an integer, as explained in the docstring of the parse method:
0 = not parsed at all
1 = parsed as a C{date}
2 = parsed as a C{time}
3 = parsed as a C{datetime}
A few words on strptime:
strptime won't be able to understand "midnight", but you can replace it with an actual hour, using something like this:
def fix_dt(raw_date):
"""Replace 'midnight', 'noon', etc."""
return raw_date.replace('midnight', '0').replace('noon', '12')
def parse_dt(raw_date):
"""Parse the fuzzy timestamps."""
return datetime.datetime.strptime(fix_dt(raw_date), '%B %d, %Y, %H')
Then:
>>> parse_dt('July 1, 2013, midnight')
datetime.datetime(2013, 7, 1, 0, 0)
You can play on strfti.me to see which one will match your format.
You should check out this other question. The answers suggest using parsedatetime and pyparsing to parse fuzzy timestamps like the one in your example. Also check this pyparsing wiki page.
You could also just combine the date withe datetime's start time:
from datetime import datetime, date
dt = date.today()
print(datetime.combine(dt, datetime.min.time()))
Related
I have a CSV dumpfile from a Blackberry IPD backup, created using IPDDump.
The date/time strings in here look something like this
(where EST is an Australian time-zone):
Tue Jun 22 07:46:22 EST 2010
I need to be able to parse this date in Python. At first, I tried to use the strptime() function from datettime.
>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z')
However, for some reason, the datetime object that comes back doesn't seem to have any tzinfo associated with it.
I did read on this page that apparently datetime.strptime silently discards tzinfo, however, I checked the documentation, and I can't find anything to that effect documented here.
Is there any way to get strptime() to play nicely with timezones?
I recommend using python-dateutil. Its parser has been able to parse every date format I've thrown at it so far.
>>> from dateutil import parser
>>> parser.parse("Tue Jun 22 07:46:22 EST 2010")
datetime.datetime(2010, 6, 22, 7, 46, 22, tzinfo=tzlocal())
>>> parser.parse("Fri, 11 Nov 2011 03:18:09 -0400")
datetime.datetime(2011, 11, 11, 3, 18, 9, tzinfo=tzoffset(None, -14400))
>>> parser.parse("Sun")
datetime.datetime(2011, 12, 18, 0, 0)
>>> parser.parse("10-11-08")
datetime.datetime(2008, 10, 11, 0, 0)
and so on. No dealing with strptime() format nonsense... just throw a date at it and it Does The Right Thing.
The datetime module documentation says:
Return a datetime corresponding to date_string, parsed according to format. This is equivalent to datetime(*(time.strptime(date_string, format)[0:6])).
See that [0:6]? That gets you (year, month, day, hour, minute, second). Nothing else. No mention of timezones.
Interestingly, [Win XP SP2, Python 2.6, 2.7] passing your example to time.strptime doesn't work but if you strip off the " %Z" and the " EST" it does work. Also using "UTC" or "GMT" instead of "EST" works. "PST" and "MEZ" don't work. Puzzling.
It's worth noting this has been updated as of version 3.2 and the same documentation now also states the following:
When the %z directive is provided to the strptime() method, an aware datetime object will be produced. The tzinfo of the result will be set to a timezone instance.
Note that this doesn't work with %Z, so the case is important. See the following example:
In [1]: from datetime import datetime
In [2]: start_time = datetime.strptime('2018-04-18-17-04-30-AEST','%Y-%m-%d-%H-%M-%S-%Z')
In [3]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: None
In [4]: start_time = datetime.strptime('2018-04-18-17-04-30-+1000','%Y-%m-%d-%H-%M-%S-%z')
In [5]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: UTC+10:00
Since strptime returns a datetime object which has tzinfo attribute, We can simply replace it with desired timezone.
>>> import datetime
>>> date_time_str = '2018-06-29 08:15:27.243860'
>>> date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f').replace(tzinfo=datetime.timezone.utc)
>>> date_time_obj.tzname()
'UTC'
Your time string is similar to the time format in rfc 2822 (date format in email, http headers). You could parse it using only stdlib:
>>> from email.utils import parsedate_tz
>>> parsedate_tz('Tue Jun 22 07:46:22 EST 2010')
(2010, 6, 22, 7, 46, 22, 0, 1, -1, -18000)
See solutions that yield timezone-aware datetime objects for various Python versions: parsing date with timezone from an email.
In this format, EST is semantically equivalent to -0500. Though, in general, a timezone abbreviation is not enough, to identify a timezone uniquely.
Ran into this exact problem.
What I ended up doing:
# starting with date string
sdt = "20190901"
std_format = '%Y%m%d'
# create naive datetime object
from datetime import datetime
dt = datetime.strptime(sdt, sdt_format)
# extract the relevant date time items
dt_formatters = ['%Y','%m','%d']
dt_vals = tuple(map(lambda formatter: int(datetime.strftime(dt,formatter)), dt_formatters))
# set timezone
import pendulum
tz = pendulum.timezone('utc')
dt_tz = datetime(*dt_vals,tzinfo=tz)
how would you go about parsing a date like that in python:
Monday, April 1st
I've tried
datetime_object = datetime.strptime(date.replace("st","").replace("rd","").replace("th","").replace("nd","").strip(), '%A, %B %d')
But obviously it would remove the "nd" from "Monday" and cause an exception
thanks
Don't replace. Strip, from the right using str.rstrip. If the unwanted characters don't exist, the string is returned as is:
>>> from datetime import datetime
>>> s = "Monday, April 1st"
>>> datetime.strptime(s.rstrip('strndh'), '%A, %B %d')
datetime.datetime(1900, 4, 1, 0, 0)
Note that the day information here (i.e. Monday) is redundant.
You can use the dateutil module (pip install py-dateutil):
>>> from dateutil import parser
>>> parser.parse("Monday, April 1st")
datetime.datetime(2017, 4, 1, 0, 0)
Also if all your string doesn't have the same length:
a = "Monday, April 1st"
if not a[-1].isdigit():
a = a[:-2]
datetime_object = datetime.strptime(a, '%A, %B %d')
I'm using python 3.5.
I have a string formatted as mm/dd/yyyy H:MM:SS AM/PM that I would like as a python datetime object.
Here is what I've tried.
date = "09/10/2015 6:17:09 PM"
date_obj = datetime.datetime.strptime(date, '%d/%m/%Y %I:%M:%S %p')
But this gets an error because the hour is not zero padded. The formatting was done per the table on the
datetime documentation, which does not allow the hour to have one digit.
I've tried splitting the date up, adding a zero and then reassembling the string back together, while this works, this seems less robust/ideal.
date = "09/10/2015 6:17:09 PM"
date = date.split()
date = date[0] + " 0" + date[1] + " " + date[2]
Any recommendation on how to get the datetime object directly, or a better method for padding the hour would be helpful.
Thank you.
There is nothing wrong with this code:
>>> date = "09/10/2015 6:17:09 PM"
>>> date_obj = datetime.datetime.strptime(date, '%m/%d/%Y %I:%M:%S %p')
>>> date_obj
datetime.datetime(2015, 9, 10, 18, 17, 9)
>>> print(date_obj)
2015-09-10 18:17:09
The individual attributes of the datetime object are integers, not strings, and the internal representation uses 24hr values for the hour.
Note that I have swapped the day and month in the format strings as you state that the input format is mm/dd/yyyy.
But it seems that you actually want it as a string with zero padded hour, so you can use datetime.strftime() like this:
>>> date_str = date_obj.strftime('%m/%d/%Y %I:%M:%S %p')
>>> print(date_str)
09/10/2015 06:17:09 PM
# or, if you actually want the output format as %d/%m/%Y....
>>> print(date_obj.strftime('%d/%m/%Y %I:%M:%S %p'))
10/09/2015 06:17:09 PM
I want to get datetimes from timestamps like the following :3/1/2014 9:55 with datetime.strptime, or something equivalent.
The month, day of month, and hour is not zero padded, but there doesn't seem to be a formatting directive listed here that is able to parse this automatically.
What's the best approach to do so? Thanks!
strptime is able to parse non-padded values. The fact that they are noted as being padded in the formatting codes table applies to strftime's output. So you can just use
datetime.strptime(datestr, "%m/%d/%Y %H:%M")
strptime isdo not require 0-padded values. See example below
datetime.strptime("3/1/2014 9:55", "%m/%d/%Y %H:%M")
output: datetime.datetime(2014, 3, 1, 9, 55)
The non-pattern way is use dateutil.parse module, it lets to parse the common date formats, even if you don't know what it is using currently
Ex:
>>> import dateutil.parser
>>>
>>> utc_time = '2014-08-13T00:00:00'
>>> verbose_time = '13-Aug-2014'
>>> some_locale = '3/1/2014 9:55'
>>> dateutil.parser.parse(utc_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(verbose_time)
datetime.datetime(2014, 8, 13, 0, 0)
>>> dateutil.parser.parse(some_locale)
datetime.datetime(2014, 3, 1, 9, 55)
Just in case this answer helps someone else -- I came here thinking I had a problem with zero padding, but it was actually to do with 12:00 vs 00:00 and the %I formatter.
The %I formatter is meant to match 12-hour-clock hours, optionally zero-padded. But depending on your data source, you might get data that says that midnight or midday is actually zero, eg:
>>> datetime.strptime('2015/01/01 0:12am', "%Y/%m/%d %I:%M%p")
ValueError: time data '2015/01/01 0:12am' does not match format '%Y/%m/%d %I:%M'
What strptime actually wanted was a 12, not a zero:
>>> datetime.strptime('2015/01/01 12:12am', "%Y/%m/%d %I:%M%p")
datetime.datetime(2015, 1, 1, 0, 12)
But we don't always control our data sources! My solution for this edge case was to catch the exception, try parsing it with a %H, with a quick check that we are in the edge case we think we are in.
def get_datetime(string):
try:
timestamp = datetime.strptime(string, "%m/%d/%Y %I:%M%p")
except ValueError:
# someone used zero for midnight?
timestamp = datetime.strptime(string, "%m/%d/%Y %H:%M%p")
assert string.lower().endswith('am')
assert timestamp.hour == 0
return timestamp
You can see the strftime document here,but in fact they aren't all working well in all platforms,for instance,%-d,%-m don't work on win7 by python 2.7,so you can accomplish like this
>>> date_str = '{d.year}-{d.month}-{d.day}'.format(d=datetime.datetime.now())
>>> print(date_str)
2016-5-23
When I call the following function, I get a struct_time obj. Is there a way to convert this into a date obj?
import time
date = time.strptime("March 2 2012", '%B %d %Y')
Thanks
Use
from datetime import datetime
date = datetime.strptime("March 2 2012", '%B %d %Y').date()
You can also do:
import dateutil.parser
datetime_obj = dateutil.parser.parse("March 2 2012")
edit:
this returns a datetime.datetime object, not a datetime.date object:
datetime.datetime(2012, 3, 2, 0, 0) #opposed to datetime.date(2012, 3, 2)
ds = time.strptime("March 2 2012", '%B %d %Y')
realdate = datetime.date(ds.tm_year, ds.tm_mon, ds.tm_mday)