DEV Community

YairMorr
YairMorr

Posted on • Originally published at Medium on

2 1

CS101 —Python exercise: counting days between two dates

CS101 — Python exercise: counting days between two dates

As part of Udacity’s Intro to Computer Science online course that I’m taking, I ran into this interesting exercise. The goal was to create a function that takes two dates as input and counts the days between them. The first date is always earlier than the second. My solution was probably not the most elegant and my code could be shorter and more efficient. The logic however was the important thing to understand, and that is also what I want to focus on in this article. This exercise was written in Python.

If we put the two input dates on a timeline, the algorithm is working from the outside in. First it calculates the days in the months of each end of the timeline, then the days in each month for each year and then the days in all the years in between. The longer the distance is between the two input dates, the more conditions necessary for the algorithm to calculate the days correctly.

1st step — Counting the days inside each month

def daysBetweenDates(year1, month1, day1, year2, month2, day2):
monthsCommonYear = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
daysCount = day2
daysCount += monthsLeapYear[month1 - 1] - day1
return daysCount

Here, daysCount is the general counter of the days between the two days, which I used throughout my function and eventually what the function returned. I assigned it to the day2 argument. I then subtracted the amount of days in month1 from day1 to get the count of days for the rest of month1. I used the list monthsCommonYear to get the exact amount of days in each month (I tend to leap years later on). This is the first because it occurs in every scenario.

This step returns the result for two input scenarios (I’m using DD/MM/YYYY format here):

  1. The two input dates have the same year and same month (i.e. 12.8.2012–28.8.2012)
  2. The two input dates have the same year but sequential months (12.8.2012–15.9.2012)

However, if the input dates are for the same year but the months are different, the function goes to the next step.

2nd step — Same year, different month

def daysBetweenDates(year1, month1, day1, year2, month2, day2):
# code from previous step
if abs(month2 - month1) > 1: # two months not sequential
if year2 - year1 == 0: # if on same year
monthCounter = month1 + 1
while monthCounter < month2:
daysCount += monthsCommonYear[monthCounter - 1]
monthCounter += 1

In this step, if the months are not sequential and the year is the same, I count the days between the first and the last month (i.e 12.8.2012–24.12.2012)

3rd step — Sequential years

if year2 - year1 >= 1: # sequencial years or more
while month1 + 1 <= 12: # calculating months in year1
daysCount += monthsCommonYear[month1]
month1 += 1
while month2 - 1 >= 1: # calcing months in year2
daysCount += monthsCommonYear[month2 - 2]
month2 -= 1

Here, if the time between the input years is 1 year or more, I add whole months to my daysCount. for year1, I add the next month (month1+1) till the end of the year. For year2, I count months from (month2–1) till the beginning of the year. I take care not to count the days in the months I counted previously. I also take care to count the correct months in my monthsCommonYear list, knowing my arguments can go from 1 to 12, but my list index goes from 0 to 11.

Distant years

if year2 - year1 > 2: # more than 1 year difference
while year1 + 1 < year2:
daysCount += 365
year1 += 1
return daysCount

The last step is pretty straightforward. I add to my daysCount the days in each year between year1 and year2. The function eventually returns daysCount.

Accounting for leap years

This exercise had an additional challenge, which made it even more interesting: the function has to tell if a year is common or leap and calculate the days accordingly. It was actually easier than I thought. The Udacity instructions linked to a Wikipedia article that offered the exact algorithm I needed and that was easily converted to a function like the one below.

def checkLeapYear(year):
if (year % 4 != 0): #if (year is not divisible by 4) then (it is a common year)
return False
elif (year % 100 != 0): #else if (year is not divisible by 100) then (it is a leap year)
return True
elif (year % 400 != 0): #else if (year is not divisible by 400) then (it is a common year)
return False
else: #else (it is a leap year)
return True

The comments in this snippet are taken straight from the description in Wikipedia.

I used this function in two types of scenarios:

  1. To determine which month list to iterate over — leap or common.
  2. To calculate the amount of days in the last scenario — when there’s a difference of more than 1 year between the two input dates.

I called checkLeapYear() 5 times in my function: 4 times to choose which month list to use (common or leap) and 1 time to add the years to my count. That’s why I preferred checkLeapYear() to return a boolean instead of the number of days in each year (365 or 366).

Here’s the first part of the function, updated to calculate leap years. Notice I added another list for leap year months (the only difference is 29 days in February).

def daysBetweenDates(year1, month1, day1, year2, month2, day2):
monthsCommonYear = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
monthsLeapYear = [ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
daysCount = day2
if checkLeapYear(year1): # days in first month
daysCount += monthsLeapYear[month1 - 1] - day1
else:
daysCount += monthsCommonYear[month1 - 1] - day1

The code I wrote for this exercise is long and encumbered, and perhaps later in my studies I will refactor it to something shorter and more efficient. The important thing for me here was exploring the logic behind the solution, rather than the way it was implemented.

Retry later

Top comments (0)

Retry later
Retry later