How to calculate difference between two dates in weeks in python

PythonDatetime

Python Problem Overview


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.

Python Solutions


Solution 1 - Python

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.

Solution 2 - Python

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()

Solution 3 - Python

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

Solution 4 - Python

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.

Solution 5 - Python

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.

Solution 6 - Python

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?

Solution 7 - Python

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)`

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrecluzeView Question on Stackoverflow
Solution 1 - PythoneumiroView Answer on Stackoverflow
Solution 2 - PythonRashmi NagarajaView Answer on Stackoverflow
Solution 3 - PythonTransformerView Answer on Stackoverflow
Solution 4 - PythonNeilView Answer on Stackoverflow
Solution 5 - PythonsbilkoloftView Answer on Stackoverflow
Solution 6 - PythonThomas Vander SticheleView Answer on Stackoverflow
Solution 7 - PythonMuhammad UsmanView Answer on Stackoverflow