Reputation: 793
Getting dates accurate is always tricky. I want to know how many weeks it takes to encapsulate 30 week days. The start day can be any day of the week day. Weekends CANNOT be counted.
For example, if I start on 1/11/2017, then for 30 week days (inclusive of starting date), the end date is 2/21/2017. That means it takes 7 weeks.
This is what I've tried:
Since datetime.isocalendar()
can be used to determine the week number in the year, my idea is to take something along the lines of:
datetime.isocalendar(enddate) - datetime.isocalendar(startdate)
.
But I believe my enddate calculation is wrong so I am getting weird numbers:
import datetime
def doit(month, day):
startdate = datetime.datetime.strptime("2017-%s-%s" % (month,day),"%Y-%m-%d")
enddate = startdate + datetime.timedelta(days=41)
print datetime.datetime.isocalendar(enddate)[1] - datetime.datetime.isocalendar(startdate)[1]
I do days=41
because each week has two weekends that we're not counting, so since 30 weekdays is normally 6 weeks, that means 6*2 + 30 = 42 days total. But since we're counting the starting date, we only add 42-1=41
days.
Why am I getting incorrect numbers? For example, if you input the dates I listed above (doit(1,11)
), I'll get 6
weeks which is not correct.
Upvotes: 2
Views: 151
Reputation: 8224
one approach would be to just simulate walking over each day, except cancelling out multiples of 5 (whole weeks) beforehand
def end_by_weekdays(start, weekdays):
weeks, weekdays = divmod(weekdays, 5)
days = 0
startday = start.weekday()
while weekdays > 0:
days += 1
if (startday + days) % 7 < 5:
weekdays -= 1
return start + timedelta(days=days + 7*weeks)
This outputs the following:
>>> end_by_weekdays(date(2017,1,11), 30)
datetime.date(2017, 2, 22)
Note that it outputs the 22nd insteaf of your expected date, which was the 21st, because I treated the starting date exclusive. Easy enough to change though if you want to.
You can then use this date to see how many weeks it takes
>>> start = date(2017,1,11)
>>> (end_by_weekdays(start, 30) - start).days / 7
6.0
or have end_by_weekdays()
return the number of days directly to avoid this back-and-forth.
Note: I used Python 3 in my code. So that last example will do an integer division on Python 2 and just output 6
Upvotes: 1
Reputation: 11
print datetime.datetime.isocalendar(enddate)[1] - datetime.datetime.isocalendar(startdate)[1]
This statement gives you correct answers if the weekday is Monday! You should think a little bit different considering this condition The start day can be any day of the week day.
Upvotes: 0