Parse date with specific format in python - python

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')

Related

How to convert a string into date-format in python?

I have a string like 23 July 1914 and want to convert it to 23/07/1914 date format.
But my code gives error.
from datetime import datetime
datetime_object = datetime.strptime('1 June 2005','%d %m %Y')
print datetime_object
Your error is in the format you are using to strip your string. You use %m as the format specifier for month, but this expects a 0 padded integer representing the month of the year (e.g. 06 for your example). What you want to use is %B, which expects an month of the year written out fully (e.g. June in your example).
For a full explanation of the datetime format specifiers please consult the documentation, and if you have any other issues please check there first.
Here is what you should be doing:
from datetime import datetime
datetime_object = datetime.strptime('1 June 2005','%d %B %Y')
s = datetime_object.strftime("%d/%m/%y")
print(s)
Output:
>>> 01/06/05
You see your strptime requires two parameters.
strptime(string[, format])
And the string will be converted to a datetime object according to a format you specify.
There are various formats
%a - abbreviated weekday name
%A - full weekday name
%b - abbreviated month name
%B - full month name
%c - preferred date and time representation
%C - century number (the year divided by 100, range 00 to 99)
%d - day of the month (01 to 31)
%D - same as %m/%d/%y
%e - day of the month (1 to 31)
%g - like %G, but without the century
%G - 4-digit year corresponding to the ISO week number (see %V).
%h - same as %b
%H - hour, using a 24-hour clock (00 to 23)
The above are some examples. Take a look here for formats
Take a goood look at these two!
%b - abbreviated month name
%B - full month name
It should be in a similar pattern to the string you provide. Confusing take a look at these examples.
>>> datetime.strptime('1 jul 2009','%d %b %Y')
datetime.datetime(2009, 7, 1, 0, 0)
>>> datetime.strptime('1 Jul 2009','%d %b %Y')
datetime.datetime(2009, 7, 1, 0, 0)
>>> datetime.strptime('jul 21 1996','%b %d %Y')
datetime.datetime(1996, 7, 21, 0, 0)
As you can see based on the format the string is turned into a datetime object. Now take a look!
>>> datetime.strptime('1 July 2009','%d %b %Y')
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
datetime.strptime('1 July 2009','%d %b %Y')
File "/usr/lib/python3.5/_strptime.py", line 510, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.5/_strptime.py", line 343, in _strptime
(data_string, format))
ValueError: time data '1 July 2009' does not match format '%d %b %Y'
Why error because jun or Jun (short form) stands for %b. When you supply a June it gets confused. Now what to do? Changed the format.
>>> datetime.strptime('1 July 2009','%d %B %Y')
datetime.datetime(2009, 7, 1, 0, 0)
Simple now converting the datetime object is simple enough.
>>> s = datetime.strptime('1 July 2009','%d %B %Y')
>>> s.strftime('%d/%m/%Y')
'01/07/2009
Again the %m is the format for displaying it in months (numbers) read more about them.
The placeholder for "Month as locale’s full name." would be %B not %m:
>>> from datetime import datetime
>>> datetime_object = datetime.strptime('1 June 2005','%d %B %Y')
>>> print(datetime_object)
2005-06-01 00:00:00
>>> print(datetime_object.strftime("%d/%m/%Y"))
01/06/2005
This should work:
from datetime import datetime
print(datetime.strptime('1 June 2005', '%d %B %Y').strftime('%d/%m/%Y'))
print(datetime.strptime('23 July 1914', '%d %B %Y').strftime('%d/%m/%Y'))
For more info you can read about strftime-strptime-behavior
%d means "Day of the month as a zero-padded decimal number."
%m means "Month as a zero-padded decimal number."
Neither day or month are supplied what you tell it to expect. What you need it %B for month (only if your locale is en_US), and %-d for day.

converting unicode to datetime in python 2.7

This should be an easy one but I am new to using datetime ...
I want to convert the following unicode to any usable datetime format:
u'Tuesday, March 28, 2017'
So I have:
>> from datetime import datetime
>> test = u'Tuesday, March 28, 2017'
>> date_time = datetime.strptime(test, '????')
I have tried a bunch of combinations for '????' but I keep getting an error saying that the format does not match. I am looking for one working example of '????' to get the unicode date into datetime type and then I can mess with the format to get it that way I want it in datetime.
If you have trouble figuring out what datetime.strptime() specifications work for your date, break down the date into components. It is much easier to puzzle out a single specification per component.
So for your date, start perhaps with the March 28 component (just Tuesday is very ambiguous, nor is it very unique to a date):
>>> from datetime import datetime
>>> datetime.strptime('March 28', '%B %d') # Full month and numeric day
datetime.datetime(1900, 3, 28, 0, 0)
>>> datetime.strptime('March 28, ', '%B %d, ') # add in the comma and space
datetime.datetime(1900, 3, 28, 0, 0)
>>> datetime.strptime('March 28, 2017', '%B %d, %Y') # add in the year
datetime.datetime(2017, 3, 28, 0, 0)
>>> datetime.strptime(', March 28, 2017', ', %B %d, %Y') # another comma and space
datetime.datetime(2017, 3, 28, 0, 0)
>>> datetime.strptime('Tuesday, March 28, 2017', '%A, %B %d, %Y') # Full weekday name
datetime.datetime(2017, 3, 28, 0, 0)
So '%A, %B %d, %Y' matches the string you tried to parse.

How to get the datetime from a string containing '2nd' for the date in Python?

I've got a couple strings from which I want to get the datetime. They are formatted like this:
Thu 2nd May 2013 19:00
I know almost how I can convert this to a datetime, except for that I'm having trouble with the "2nd". I now have the following
>>> datetime.strptime('Thu 02 May 2013 19:00', '%a %d %B %Y %H:%M')
datetime.datetime(2013, 5, 2, 19, 0)
which works fine with a zero padded number for the day of the month, but when I try the 2nd, it gives a ValueError:
>>> datetime.strptime('Thu 2nd May 2013 19:00', '%a %d %B %Y %H:%M')
Traceback (most recent call last):
File "<input>", line 1, in <module>
(data_string, format))
ValueError: time data 'Thu 2nd May 2013 19:00' does not match format '%a %d %B %Y %H:%M'
In the list of datetime directives I can't find anything relating to ordered values (1st, 2nd, 3rd etc) for dates. Does anybody know how I can get this to work? All tips are welcome!
Consider using dateutil.parser.parse.
It's a third party library that has a powerful parser which can handle these kinds of things.
from dateutil.parser import parse
s = 'Thu 2nd May 2013 19:00'
d = parse(s)
print(d, type(d))
# 2013-05-02 19:00:00 <class 'datetime.datetime'>
A brief caveat (doesn't really occur in your case): if dateutil can't find an aspect of your date in the string (say you leave out the month) then it will default to the default argument. This defaults to the current date with the time 00:00:00. You can obviously over-write this if necessary with a different datetime object.
The easiest way to install dateutil is probably using pip with the command pip install python-dateutil.
You can preparse the original string to adjust the day to be suitable for your strptime, eg:
from datetime import datetime
import re
s = 'Thu 2nd May 2013 19:00'
amended = re.sub('\d+(st|nd|rd|th)', lambda m: m.group()[:-2].zfill(2), s)
# Thu 02 May 2013 19:00
dt = datetime.strptime(amended, '%a %d %B %Y %H:%M')
# 2013-05-02 19:00:00
It's straightforward to remove the suffix from the date without using regular expressions or an external library.
def remove_date_suffix(s):
parts = s.split()
parts[1] = parts[1].strip("stndrh") # remove 'st', 'nd', 'rd', ...
return " ".join(parts)
Then it's as simple as using strptime as you'd expect:
>>> s = "Thu 2nd May 2013 19:00"
>>> remove_date_suffix(s)
'Thu 2 May 2013 19:00'
>>> datetime.strptime(remove_date_suffix(s), '%a %d %B %Y %H:%M')
datetime.datetime(2013, 5, 2, 19, 0)
import re
from datetime import datetime
def proc_date(x):
return re.sub(r"\b([0123]?[0-9])(st|th|nd|rd)\b",r"\1",x)
>>> x='Thu 2nd May 2013 19:00'
>>> proc_date(x)
'Thu 2 May 2013 19:00'
>>> datetime.strptime(proc_date(x), '%a %d %B %Y %H:%M')
datetime.datetime(2013, 5, 2, 19, 0)

Converting dates with times like "midnight"

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()))

Python converting "March 2 2012" into a datetime object

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)

Categories

Resources