Reputation: 115
I have two dates between which I need to find out how many Mon- Fri are coming(except for Sta, Sun), everyday should be counted
Currently I am thinking this:
import calendar
import datetime
start_date = datetime.datetime.strptime("01/01/2017",'%d/%m/%Y')
end_date = datetime.datetime.strptime("31/01/2017",'%d/%m/%Y')
week_arr = [0] * 7
calendar.day_name[start_date.weekday()] ## will give me name of day
"""
As I receive Monday I will increment week_arr[0] by 1, Tuesday
week_arr[1]+= 1,
"""
I am not getting how to do it effectively so that I dont use much line of code(less if -else and for loops), may be some tricks in pandas.
Upvotes: 10
Views: 19594
Reputation: 2198
You can define a function and use it like this :
def num_days_between( start, end, week_day):
num_weeks, remainder = divmod( (end-start).days, 7)
if ( week_day - start.weekday() ) % 7 < remainder:
return num_weeks + 1
else:
return num_weeks
where week_day is day number you wan to calculate count.
Upvotes: 9
Reputation: 1
I found a simple and easy to understand code using for loop. Take first date identify its weekday with "%a" compare it with your intrested weekday if found increment a count value. and repeat the steps till your last day. Code is as below for your refrence i took monday as my intrested weekdays.
import datetime
A1=datetime.datetime.strptime("1/23/2016", "%m/%d/%Y")
A2=datetime.datetime.strptime("11/10/2016", "%m/%d/%Y")
count=0
week="Mon"
for i in range ((A2-A1).days): #gives the no of days from A1 to A2
if A1.strftime("%a")==week:
count+=1
A1+=datetime.timedelta(days=1)
print(count)
https://www.w3schools.com/python/python_datetime.asp
Upvotes: 0
Reputation: 41
Number of Mondays in 2020 can be got using numpy library
import numpy as np
np.busday_count('2020', '2021', weekmask='Mon')
Upvotes: 4
Reputation: 1338
If anyone need an even simpler answer,
from datetime import date
d1 = date(2017, 1, 4)
d2 = date(2017, 1, 31)
count = 0
for d_ord in range(d1.toordinal(), d2.toordinal()):
d = date.fromordinal(d_ord)
if (d.weekday() == 4):
count += 1
print(count)
Upvotes: 0
Reputation: 4135
This is efficient - even in the face of ten thousands of days between start and end - and still very flexible (it iterates at most 7 times inside the sum function):
def intervening_weekdays(start, end, inclusive=True, weekdays=[0, 1, 2, 3, 4]):
if isinstance(start, datetime.datetime):
start = start.date() # make a date from a datetime
if isinstance(end, datetime.datetime):
end = end.date() # make a date from a datetime
if end < start:
# you can opt to return 0 or swap the dates around instead
raise ValueError("start date must be before end date")
if inclusive:
end += datetime.timedelta(days=1) # correct for inclusivity
try:
# collapse duplicate weekdays
weekdays = {weekday % 7 for weekday in weekdays}
except TypeError:
weekdays = [weekdays % 7]
ref = datetime.date.today() # choose a reference date
ref -= datetime.timedelta(days=ref.weekday()) # and normalize its weekday
# sum up all selected weekdays (max 7 iterations)
return sum((ref_plus - start).days // 7 - (ref_plus - end).days // 7
for ref_plus in
(ref + datetime.timedelta(days=weekday) for weekday in weekdays))
This takes both datetime.date
as well as datetime.datetime
objects for start
and end
, respectively.
Also, you can choose between a closed (inclusive=True
) and a half-open (inclusive=False
) interval.
By default, it calculates the number of workdays between the dates, but you can choose any set of weekdays (weekend days: weekdays=[5, 6]
) or single weekdays (Wednesdays: weekdays=2
) as well.
Upvotes: 2
Reputation: 1234
This code still uses a for loop and an if/else.
import datetime
import calendar
def weekday_count(start, end):
start_date = datetime.datetime.strptime(start, '%d/%m/%Y')
end_date = datetime.datetime.strptime(end, '%d/%m/%Y')
week = {}
for i in range((end_date - start_date).days):
day = calendar.day_name[(start_date + datetime.timedelta(days=i+1)).weekday()]
week[day] = week[day] + 1 if day in week else 1
return week
print(weekday_count("01/01/2017", "31/01/2017"))
# prints result
# {'Monday': 5, 'Tuesday': 5, 'Friday': 4, 'Wednesday': 4, 'Thursday': 4, 'Sunday': 5, 'Saturday': 4}
Upvotes: 6