views:

56

answers:

4

Hi all,

What I am trying to accomplish is very simple: creating a loop from a range (pretty self explanatory below) that will insert the month into the datetime object. I know %d requires an integer, and I know that 'month' type is int...so I'm kind of stuck as to why I can't substitute my month variable. Here is my code:

all_months=range(1,13)
for month in all_months:
    month_start = (datetime.date(2010,'%d',1))%month
    next_month_begin= datetime.date(2010,'%d',1)%(month+1)  
    month_end=next_month_begin - timedelta(days=1)
    print month_start                                        
    print month_end

What am I doing wrong?

All help appreciated! Thanks

A: 

month is a variable and you can use it to create the datetime object. I think you want to do the following:

month_start = datetime.date(2010, month, 1)
next_month_begin = datetime.date(2010, month+1, 1)

That will work, because datetime.date() requires 3 integer arguments. '%d' % month would instead format the integer month as string. '%04d' % 3 for example would format the number 3 with 4 digits and leading zeros. But it's important to know, that even the (nearly unformatted) string "3" is different to the number 3 in Python.

And you can't write datetime(...) % 3 because the % operator will only work when used on a format string like the previous "%03d" % 3 example and not on a datetime object.

But other types might also accept the % operator (not including datetime objects). For example, integers accept the % operator to get the remainder of a division: 3 % 2 # returns 1. But there, the meaning of % is completely different, because the meaning of the operator depends on the types involved. For example, try 3 + 2 and "3" + "2". There, the meaning of + differs (integer addition vs. string concatenation), because the types are different too.

tux21b
thank you...I definitely feel dumb!
DalivDali
+1  A: 

There are a few things that you need to fix here.

EDIT: First, be careful with your range, since you are using month+1 to create next_month_begin, you do not want this to be greater than 12 or you will get an error.

Next, when you are trying to create the date object you are passing the month in as a string when you use (datetime.date(2010,'%d',1))%month. Your code probably throwing this error TypeError: an integer is required.

You need to give it the integer representing the month, not a string of the integer (there is a difference between 1 and '1'). This is also a simple fix, since you have variable named month that is already an integer, just use that instead of making a string. So you code should be something like:

month_start = datetime.date(2010,month,1)

I think you can figure out how to apply this to your next_month_begin assignment.

The last problem is that you need to use datetime.timedelta to tell Python to look in the datetime module for the timedelta() function -- your program would currently give you an error saying that timedelta is not defined.

Let me know if you have any problems applying these fixes. Be sure to include what the error you may be getting as well.

swanson
whoops, my mistake, it was the month+1 that was causing problems, thanks
swanson
not a problem, deleting previous comment
Adam Bernier
Great! Everything works fine with these fixes except for the fact (which you noted) that datetime does not accept the number 13...am trying to resolve this issue. Would I have to include an exception for December, stating that it simply iterates until the 31st? Or is there a cleaner way?
DalivDali
The datetime module, unfortunately, does not allow you to use timedelta() to add a month to your date and since months do not have the same number of days it is tricky. I think that probably the easiest way is to just check if the month is 12 and then add a special case for 12/31. This is probably not the most clean way but it should serve your goals. Also feel free to vote up any answers that were helpful to you.
swanson
Much appreciated, swanson- mil gracias ('a thousand thanks,' en espanol)
DalivDali
de nada :) good luck continuing with python - its a fun language
swanson
+2  A: 

You've got other answers, but here's a way to get the last day of the month. Adding 31 days will get you into the next month regardless of the number of days in the current month, then moving back to the first and subtracting a day will give the ending date.

import datetime
for month in range(1,13):
    month_start = datetime.date(2010,month,1)
    into_next_month = month_start + datetime.timedelta(days=31)
    month_end = into_next_month.replace(day=1) - datetime.timedelta(days=1)
    print month_start,month_end                                       
Mark Tolonen
A: 

Check out the calendar module (http://docs.python.org/library/calendar.html).

It has batteries included for this sort of thing...

You could just do:

from calendar import Calendar
def start_and_end_days(year, month):
    cal = Calendar()
    month_days = [day for day in cal.itermonthdays(year, month) if day.month == month]
    first_day = month_days[0]
    last_day = month_days[-1]
    return (first_day, last_day)
Nathan.Rice