Does python offer a way to easily get the current week of the month (1:4) ?
I know this is years old, but I spent a lot of time trying to find this answer. I made my own method and thought I should share.
The calendar module has a monthcalendar method that returns a 2D array where each row represents a week. For example:
import calendar
calendar.monthcalendar(2015,9)
result:
[[0,0,1,2,3,4,5],
[6,7,8,9,10,11,12],
[13,14,15,16,17,18,19],
[20,21,22,23,24,25,26],
[27,28,29,30,0,0,0]]
So numpy's where is your friend here. And I'm in USA so I want the week to start on Sunday and the first week to be labelled 1:
import calendar
import numpy as np
calendar.setfirstweekday(6)
def get_week_of_month(year, month, day):
x = np.array(calendar.monthcalendar(year, month))
week_of_month = np.where(x==day)[0][0] + 1
return(week_of_month)
get_week_of_month(2015,9,14)
returns
3
Josh's answer has to be tweaked slightly to accomodate the first day falling on a Sunday.
def get_week_of_month(date):
first_day = date.replace(day=1)
day_of_month = date.day
if(first_day.weekday() == 6):
adjusted_dom = (1 + first_day.weekday()) / 7
else:
adjusted_dom = day_of_month + first_day.weekday()
return int(ceil(adjusted_dom/7.0))
Josh' answer seems the best but I think that we should take into account the fact that a week belongs to a month only if its Thursday falls into that month. At least that's what the iso says.
According to that standard, a month can have up to 5 weeks. A day could belong to a month, but the week it belongs to may not.
I have taken into account that just by adding a simple
if (first_day.weekday()>3) :
return ret_val-1
else:
return ret_val
where ret_val is exactly Josh's calculated value. Tested on June 2017 (has 5 weeks) and on September 2017. Passing '2017-09-01' returns 0 because that day belongs to a week that does not belong to September.
The most correct way would be to have the method return both the week number and the month name the input day belongs to.
If your first week starts on the first day of the month you can use integer division:
import datetime day_of_month = datetime.datetime.now().day week_number = (day_of_month - 1) // 7 + 1
Check out the package Pendulum
>>> dt = pendulum.parse('2018-09-30')
>>> dt.week_of_month
5
Say we have some month's calender as follows:
Mon Tue Wed Thur Fri Sat Sun
1 2 3
4 5 6 7 8 9 10
We say day 1 ~ 3 belongs to week 1 and day 4 ~ 10 belongs to week 2 etc.
In this case, I believe the week_of_month for a specific day should be calculated as follows:
import datetime
def week_of_month(year, month, day):
weekday_of_day_one = datetime.date(year, month, 1).weekday()
weekday_of_day = datetime.date(year, month, day)
return (day - 1)//7 + 1 + (weekday_of_day < weekday_of_day_one)
However, if instead we want to get the nth of the weekday that date is, such as day 1 is the 1st Friday, day 8 is the 2nd Friday, and day 6 is the 1st Wednesday, then we can simply return (day - 1)//7 + 1