Paired pairs of months a day

Let's say I have 2 lines “January 2010” and “March 2010”, and I want to parse it so that it returns 2 datetime objects: January 1, 2010 and March 31, 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 say that the last day of the month is for Mar-2010 (getting the first day is trivial, its always 1 in this case, if I don't want the first business day of the month).

Any suggestions? Thanks in advance.

+4
source share
5 answers

strptime do parsing in dates on your behalf:

 def firstofmonth(MmmYyyy): return datetime.datetime.strptime(MmmYyyy, '%b-%Y').date() 

much better than messing with tokenization, regexp, and c! -).

To get the date of the last day of the month, you can really 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 TOTALLY do it neatly with just a date-time, for example, a USER working approach:

 def lastofmonth(MmmYyyy): first = firstofmonth(MmmYyyy) return first.replace(month=first.month+1, day=1 ) - datetime.timedelta(days=1) 

but, alas!, it breaks into December, and the code necessary for the December case makes the general approach more dense than the calendar, -).

+5
source

I highly recommend using the python timeseries module, which you can download and read here:

http://pytseries.sourceforge.net/

You should also use the dateutil package to parse 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 depends on external modules, but they are very powerful and well written.

+3
source
 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')) 

What 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 
+2
source

I know that a lot of time has passed, but if someone needs:

 from dateutil import rrule from dateutil import parser from datetime import datetime first_day = parser.parse('Jan-2010',default=datetime(1,1,1)) last_day = rrule.rrule(rrule.MONTHLY,count=1,bymonthday=-1, bysetpos=1,dtstart=parser.parse('Mar-2010')) 
+1
source

Riff on Alexa Martelli:

 import datetime def lastofmonthHelper(MmmYyyy): # Takes a date return MmmYyyy.replace(year=MmmYyyy.year+(MmmYyyy.month==12), month=MmmYyyy.month%12 + 1, day=1) - datetime.timedelta(days=1) >>> for month in range(1,13): ... t = datetime.date(2009,month,1) ... print t, lastofmonthHelper(t) ... 2009-01-01 2009-01-31 2009-02-01 2009-02-28 2009-03-01 2009-03-31 2009-04-01 2009-04-30 2009-05-01 2009-05-31 2009-06-01 2009-06-30 2009-07-01 2009-07-31 2009-08-01 2009-08-31 2009-09-01 2009-09-30 2009-10-01 2009-10-31 2009-11-01 2009-11-30 2009-12-01 2009-12-31 

You do not need to use the first day of the month, BTW. I would put this in a comment, but we all know how formatting would work. Feel free to promote Alex.

If you call the result of calling firstofmonth (), you get the desired result:

 >>> lastofmonthHelper(firstofmonth('Apr-2009')) datetime.date(2009, 4, 30) 
0
source

All Articles