Let's say i have 2 strings 'Jan-2010' and 'Mar-2010' and i want to parse it such that it returns 2 datetime objects: 1-Jan-2010 and 31-Mar-2010 (i.e. the last day).
What would be the best strategy in python? Should i just split the string into tokens or use regular expressions and then use the calendar functions to get say the last day of the month for 'Mar-2010' (getting the first day is trivial, its always 1 in this case unless i wanted the first working day of the month).
Any suggestions? Thanks in advance.
strptime
does the string parsing into dates on your behalf:
def firstofmonth(MmmYyyy):
return datetime.datetime.strptime(MmmYyyy, '%b-%Y').date()
much better than messing around with tokenization, regexp, &c!-).
To get the date of the last day of the month, you can indeed use the calendar module:
def lastofmonth(MmmYyyy):
first = firstofmonth(MmmYyyy)
_, lastday = calendar.monthrange(first.year, first.month)
return datetime.date(first.year, first.month, lastday)
You could ALMOST do it neatly with datetime alone, e.g., an ALMOST working approach:
def lastofmonth(MmmYyyy):
first = firstofmonth(MmmYyyy)
return first.replace(month=first.month+1, day=1
) - datetime.timedelta(days=1)
but, alas!, this breaks for December, and the code needed to specialcase December makes the overall approach goofier than calendar affords;-).
I highly recommend using the python timeseries module, which you can download and read about here:
http://pytseries.sourceforge.net/
You should also use the dateutil package for parsing the date string, which you can find here:
http://labix.org/python-dateutil
Then you can do something like this
import datetime
import dateutil.parser
import scikits.timeseries as TS
m1 = TS.Date('M', datetime=dateutil.parser.parse('Jan-2010'))
m2 = TS.Date('M', datetime=dateutil.parser.parse('Mar-2010'))
d1 = m1.asfreq('D', relation='START') # returns a TS.Date object
d2 = m2.asfreq('D', relation='END')
firstDay = d1.datetime
lastDay = d2.datetime
This solution is dependent out outside modules, but they're very powerful and well written.
from datetime import datetime, timedelta
def first_day(some_date):
return some_date.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
def next_month(some_date):
return first_day(first_day(some_date) + timedelta(days=31))
def last_day(some_date):
return next_month(some_date) - timedelta(days=1)
# testing:
months = [('Jan-2010', 'Mar-2010'), # your example
('Apr-2009', 'Apr-2009'), # same month, 30 days
('Jan-2008', 'Dec-2008'), # whole year
('Jan-2007', 'Feb-2007')] # february involved
for date1, date2 in months:
print first_day(datetime.strptime(date1, '%b-%Y')),
print '-',
print last_day(datetime.strptime(date2, '%b-%Y'))
That prints:
2010-01-01 00:00:00 - 2010-03-31 00:00:00
2009-04-01 00:00:00 - 2009-04-30 00:00:00
2008-01-01 00:00:00 - 2008-12-31 00:00:00
2007-01-01 00:00:00 - 2007-02-28 00:00:00
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With