61

I'm trying to calculate the difference between two dates in "weeks of year". I can get the datetime object and get the days etc but not week numbers. I can't, of course, subtract dates because weekends can't be ensured with that.

I tried getting the week number using d1.isocalendar()[1] and subtracting d2.isocalendar()[1] but the issue is that isocalendar()[1] returns December 31, 2012 as week 1 (which supposedly is correct) but that means my logic cannot span over this date.

For reference, here's my complete code:

def week_no(self): ents = self.course.courselogentry_set.all().order_by('lecture_date') l_no = 1 for e in ents: if l_no == 1: starting_week_of_year = e.lecture_date.isocalendar()[1] # get week of year initial_year = e.lecture_date.year if e == self: this_year = e.lecture_date.year offset_week = (this_year - initial_year) * 52 w_no = e.lecture_date.isocalendar()[1] - starting_week_of_year + 1 + offset_week break l_no += 1 return w_no 

With this code, the lecture on Dec 31, 2012 ends up being -35.

7 Answers 7

88

How about calculating the difference in weeks between the Mondays within weeks of respective dates? In the following code, monday1 is the Monday on or before d1 (the same week):

from datetime import datetime, timedelta monday1 = (d1 - timedelta(days=d1.weekday())) monday2 = (d2 - timedelta(days=d2.weekday())) print 'Weeks:', (monday2 - monday1).days / 7 

Returns 0 if both dates fall withing one week, 1 if on two consecutive weeks, etc.

Sign up to request clarification or add additional context in comments.

13 Comments

Can you just elaborate your code by explaining it, specially on the monday1 and monday2 calculations.
Works perfectly, spans across years and weeks. Very concise too. Thanks a lot :)
I get an error with days() : (Pdb) (monday2 - monday1).days() *** TypeError: 'int' object is not callable (Pdb) (monday2 - monday1).days 77
Guess I'm a bit late here.. Shouldn't the last line be: print (monday2 - monday1).days/7 instead of print (monday2 - monday1).days()/7
I just edited the answer so that "days" is used instead of "days()". So the last few comments will no longer be relevant (assuming the edit is accepted). I added 'Weeks:' only because edits have to change at least 6 characters.
|
49

You may want to refer the Python CookBook (2005 edition) Recipe 3.3. The following code snippet is from the cookbook, does what you require.

from dateutil import rrule import datetime def weeks_between(start_date, end_date): weeks = rrule.rrule(rrule.WEEKLY, dtstart=start_date, until=end_date) return weeks.count() 

1 Comment

Thanks. Haven't tested this out but even it works, I think eumiro's solution is more elegant. +1 though for an alternative :)
29

This is a very simple solution with less coding everyone would understand.

from datetime import date d1 = date(year, month, day) d2 = date(year, month, day) result = (d1-d2).days//7 

4 Comments

Works tested (date(2018, 5, 3) - date(2017, 12, 25)).days/7 and verified timeanddate.com/date/…
Good, it works for you, should be this (date(2018, 5, 3) - date(2017, 12, 25)).days//7
Nice. I missed the floor division. The floor operator is better! I was relying on python 2's default integer division which behaves the same as // but that is not true in python 3. stackoverflow.com/questions/183853/…
This solution doesn't give the difference in calendar weeks. For example, if d1 is a Friday and d2 is Tuesday of the following week, there are 4 days between the two dates which would result in 0 weeks but the answer should be 1 calendar week.
4

The solution above has a bug (I can't add a comment due to low reputation). It doesn't account for hour differences.

# This code has a bug. monday1 = (d1 - timedelta(days=d1.weekday())) monday2 = (d2 - timedelta(days=d2.weekday())) 

Counter example of 2 dates more than a week apart:

Timestamp1: 1490208193270795 (22 Mar 2017 18:43:13 GMT) Monday1: 20 Mar 2017 18:43:13 GMT Timestamp2: 1489528488744290 (14 Mar 2017 21:54:48 GMT) Monday2: 13 Mar 2017 21:54:48 GMT 

Using that code it returns 0 as week diff when it should be 1. Need to zero out the hours/minutes/seconds as well.

Comments

2

To determine how many weeks are spanned by two dates. eg From 3rd Oct to 13th Oct

 October 2015 Mo 5 12 19 26 Tu 6 13 20 27 We 7 14 21 28 Th 1 8 15 22 29 Fr 2 9 16 23 30 Sa 3 10 17 24 31 Su 4 11 18 25 

Code:

 import math, datetime start_date = datetime.date(2015, 10, 3) start_date_monday = (start_date - datetime.timedelta(days=start_date.weekday())) end_date = datetime.date(2015, 10, 13) num_of_weeks = math.ceil((end_date - start_date_monday).days / 7.0) 

Equals 3 weeks.

Comments

1

Edited Best Answer

from datetime import timedelta monday1 = (d1 - timedelta(days=d1.weekday())) monday2 = (d2 - timedelta(days=d2.weekday())) diff = monday2 - monday1 noWeeks = (diff.days / 7) + math.ceil(diff.seconds/86400) print('Weeks:', noWeeks)` 

2 Comments

Could you please elaborate your answer and what is the improvement?
Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes
0

You're a bit vague on what 'difference in weeks' means exactly. Is 6 days difference one week or zero ? Is eight days difference one week or two ?

In any case, why can't you simply find the difference in another unit (seconds or days) and divide by the appropriate amount, with your prefered rounding for weeks?

1 Comment

Thanks for the input. I was actually talking about difference in "week of year". So, it's not sufficient to say "6 days". If first day is monday, second is thursday, week difference is 0 but if one is saturday and two is sunday, week difference is 1.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.