Reputation: 2780
I have the following problem: Given a year and a month, determine the week numbers that are contained in that particular month, i.e., October 2017 contains week numbers 39,40,41,42,43,44. Caveat: As a rule, week starts in Monday and ends in Sunday. I have a cumbersome code that does the trick but I would like to know if there is a more elegant or Pythonistic way of doing this.
from datetime import datetime
import calendar
def get_week_numbers_in_month(year,month):
list_of_weeks = []
initial_day = 1
ending_day = calendar.monthrange(int(year),int(month))[1] #get the last day of month
initial_week = int(datetime(year,month,initial_day).isocalendar()[1])
ending_week = int(datetime(year,month,ending_day).isocalendar()[1])
counter = initial_week
while(counter <= ending_week):
list_of_weeks.append(counter)
counter += 1
return list_of_weeks
print("Your month contains the following weeks:\n"+str(get_week_numbers_in_month(2017,10)))
# result: Your month contains the following weeks:
# [39, 40, 41, 42, 43, 44]
Upvotes: 1
Views: 1596
Reputation: 53
My approach 😊
from datetime import datetime
import calendar
def get_week_numbers_in_month(year, month) -> list:
ending_day = calendar.monthrange(year, month)[1] # get the last day of month
initial_week = datetime(year, month, 1).isocalendar()[1]
ending_week = datetime(year, month, ending_day).isocalendar()[1]
res = list(range(initial_week, ending_week + 1))
if not res:
week_num = 52 if initial_week != 53 else 53
res = list(range(initial_week, week_num + 1)) + list(range(1, ending_week + 1))
return res
Output
>>> print(get_week_numbers_in_month(2021, 1))
[52, 1, 2, 3, 4]
>>>
Upvotes: 1
Reputation: 56
I would have added this as a comment, but do not have enough reputation to do so...
It looks like the approved answer does not actually work for the month of December as it will sometimes spill over into week 1. Also, why is it adding a week to the end when it creates the range?
Accepted answer:
def get_week_numbers_in_month(year,month):
ending_day = calendar.monthrange(year, month)[1] #get the last day of month
initial_week = datetime(year, month, 1).isocalendar()[1]
ending_week = datetime(year, month, ending_day).isocalendar()[1]
return range(initial_week, ending_week + 1)
print(get_week_numbers_in_month(2019,12))
# range(48, 2)
print(list(get_week_numbers_in_month(2019,12)))
# []
You would actually need to add some additional logic to build the list yourself instead of using a range
def get_week_numbers_in_month(year,month):
ending_day = calendar.monthrange(year, month)[1] #get the last day of month
initial_week = datetime(year, month, 1).isocalendar()[1]
ending_week = datetime(year, month, ending_day).isocalendar()[1]
# Adding logic to build week list if month is December (12)
if month = 12:
week_list = []
while week != ending_week:
if week not in week_list:
week_list.append(week)
else:
if week >= 52:
week = 1
else:
week += 1
week_list.append(week)
else:
week_list = list(range(initial_week, ending_week))
return week_list
print(get_week_numbers_in_month(2019,12))
# [48, 49, 50, 51, 52, 1]
Upvotes: 0
Reputation: 54223
You could simply return a range and avoid the whole initializing process. Also, note that isocalendar
returns a 3-tuple of integers:
from datetime import datetime
import calendar
def get_week_numbers_in_month(year,month):
ending_day = calendar.monthrange(year, month)[1] #get the last day of month
initial_week = datetime(year, month, 1).isocalendar()[1]
ending_week = datetime(year, month, ending_day).isocalendar()[1]
return range(initial_week, ending_week + 1)
print("Your month contains the following weeks:")
print(get_week_numbers_in_month(2017,10))
# range(39, 45)
If you really want to return a list, simply return list(range(...))
Upvotes: 1