How to calculate number of days between two given dates

If I have two dates (ex. '8/18/2008' and '9/26/2008' ), what is the best way to get the number of days between these two dates?

61.6k 41 41 gold badges 162 162 silver badges 180 180 bronze badges asked Sep 29, 2008 at 23:36 191k 98 98 gold badges 227 227 silver badges 206 206 bronze badges

17 Answers 17

If you have two date objects, you can just subtract them, which computes a timedelta object.

from datetime import date d0 = date(2008, 8, 18) d1 = date(2008, 9, 26) delta = d1 - d0 print(delta.days) 

See this answer for another example.

616 5 5 silver badges 14 14 bronze badges answered Sep 29, 2008 at 23:41 32.8k 17 17 gold badges 63 63 silver badges 73 73 bronze badges

Great answers here. Since a lot of the folks might be using pandas data frame, thought might be useful to check the link on how to convert from np.datetime64 to python datetime stackoverflow.com/questions/52982056/…

Commented May 15, 2019 at 22:54 The nice thing is that this solution also returns correct delta for leap years. Commented May 2, 2020 at 8:19

That's why i love python - things like this, which make an technical complex problem feel solved in a natural way

Commented Jul 30, 2020 at 9:40 Does this account for leap seconds? Commented Oct 23, 2020 at 12:57 Note that the result is not inclusive, i.e., 2019/05/01 to 2019/05/03 counts as 2 days. Commented Nov 24, 2021 at 3:18

Using the power of datetime:

from datetime import datetime date_format = "%m/%d/%Y" a = datetime.strptime('8/18/2008', date_format) b = datetime.strptime('9/26/2008', date_format) delta = b - a print(delta.days) # that's it how to calculate number of days between two given dates 
1 1 1 silver badge answered Sep 29, 2008 at 23:41 dguaraglia dguaraglia 5,964 1 1 gold badge 27 27 silver badges 23 23 bronze badges actually, the date class would be more appropriate in this case than datetime. Commented Sep 30, 2008 at 15:08 @JeremyCantrell And yet, even eight years later, date still lacks its own equivalent to strptime() . Commented Feb 12, 2016 at 14:57 Why needs strptime the format arg? Should be clear with the first arg date which has a format. Commented May 19, 2018 at 11:59

Days until Christmas:

>>> import datetime >>> today = datetime.date.today() >>> someday = datetime.date(2008, 12, 25) >>> diff = someday - today >>> diff.days 86 
18.6k 9 9 gold badges 44 44 silver badges 68 68 bronze badges answered Sep 29, 2008 at 23:43 Harley Holcombe Harley Holcombe 181k 15 15 gold badges 72 72 silver badges 63 63 bronze badges Updated answer: -4602 Commented Aug 2, 2021 at 0:07 Correction: today = datetime.today() Commented Sep 20, 2022 at 13:00

everyone has answered excellently using the date, let me try to answer it using pandas

dt = pd.to_datetime('2008/08/18', format='%Y/%m/%d') dt1 = pd.to_datetime('2008/09/26', format='%Y/%m/%d') (dt1-dt).days 

This will give the answer. In case one of the input is dataframe column. simply use dt.days in place of days

(dt1-dt).dt.days 
answered Nov 13, 2019 at 6:22 Amit Gupta Amit Gupta 2,848 4 4 gold badges 28 28 silver badges 39 39 bronze badges

You want the datetime module.

>>> from datetime import datetime >>> datetime(2008,08,18) - datetime(2008,09,26) datetime.timedelta(4) 
>>> import datetime >>> today = datetime.date.today() >>> print(today) 2008-09-01 >>> last_year = datetime.date(2007, 9, 1) >>> print(today - last_year) 366 days, 0:00:00 
91 1 1 silver badge 10 10 bronze badges answered Sep 29, 2008 at 23:43 12.7k 14 14 gold badges 65 65 silver badges 100 100 bronze badges How do I get this without the 0:00:00 part? Commented Sep 12, 2019 at 23:17 @VickiB delta = today - last_year print(delta.days) Commented Jan 7, 2020 at 13:18

Note the calculation order: from_earlier_time - to_later_time, then you get a positive timedelta! Not the other way. Kinda weird.

Commented Jan 1, 2021 at 0:25
from datetime import datetime start_date = datetime.strptime('8/18/2008', "%m/%d/%Y") end_date = datetime.strptime('9/26/2008', "%m/%d/%Y") print abs((end_date-start_date).days) 
43.9k 11 11 gold badges 83 83 silver badges 100 100 bronze badges answered Apr 26, 2012 at 10:58 Prasanna Ranganathan Prasanna Ranganathan 189 1 1 silver badge 2 2 bronze badges This adds nothing new compared to the answers given 4 years earlier. -1. Commented Jun 26, 2017 at 23:16

+1 for the use of abs() , which is useful when the compared dates are unknown beforehand and it is the difference you are interested in. If your second date in datetime.strptime(date, date) is later than the first date, the result will be negative. abs() makes all input absolute (ie. positive).

Commented Jul 5, 2018 at 20:06

It also can be easily done with arrow :

import arrow a = arrow.get('2017-05-09') b = arrow.get('2017-05-11') delta = (b-a) print delta.days 
answered May 11, 2017 at 18:35 346 2 2 silver badges 6 6 bronze badges

without using Lib just pure code:

#Calculate the Days between Two Date daysOfMonths = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] def isLeapYear(year): # Pseudo code for this algorithm is found at # http://en.wikipedia.org/wiki/Leap_year#Algorithm ## if (year is not divisible by 4) then (it is a common Year) #else if (year is not divisable by 100) then (ut us a leap year) #else if (year is not disible by 400) then (it is a common year) #else(it is aleap year) return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 def Count_Days(year1, month1, day1): if month1 ==2: if isLeapYear(year1): if day1 < daysOfMonths[month1-1]+1: return year1, month1, day1+1 else: if month1 ==12: return year1+1,1,1 else: return year1, month1 +1 , 1 else: if day1 < daysOfMonths[month1-1]: return year1, month1, day1+1 else: if month1 ==12: return year1+1,1,1 else: return year1, month1 +1 , 1 else: if day1 < daysOfMonths[month1-1]: return year1, month1, day1+1 else: if month1 ==12: return year1+1,1,1 else: return year1, month1 +1 , 1 def daysBetweenDates(y1, m1, d1, y2, m2, d2,end_day): if y1 >y2: m1,m2 = m2,m1 y1,y2 = y2,y1 d1,d2 = d2,d1 days=0 while(not(m1==m2 and y1==y2 and d1==d2)): y1,m1,d1 = Count_Days(y1,m1,d1) days+=1 if end_day: days+=1 return days # Test Case def test(): test_cases = [((2012,1,1,2012,2,28,False), 58), ((2012,1,1,2012,3,1,False), 60), ((2011,6,30,2012,6,30,False), 366), ((2011,1,1,2012,8,8,False), 585 ), ((1994,5,15,2019,8,31,False), 9239), ((1999,3,24,2018,2,4,False), 6892), ((1999,6,24,2018,8,4,False),6981), ((1995,5,24,2018,12,15,False),8606), ((1994,8,24,2019,12,15,True),9245), ((2019,12,15,1994,8,24,True),9245), ((2019,5,15,1994,10,24,True),8970), ((1994,11,24,2019,8,15,True),9031)] for (args, answer) in test_cases: result = daysBetweenDates(*args) if result != answer: print "Test with data:", args, "failed" else: print "Test case passed!" test() 
answered Feb 5, 2018 at 22:37 Muhammad Elsayeh Muhammad Elsayeh 111 1 1 silver badge 3 3 bronze badges

There seems to be a problem with your code. If you try daysBetweenDates(*(2013,2,28,2013,1,1,False)), it will end up in an infinite loop because the condition y1 > y2 in the daysBetweenDates is not very well thought-out. Moreover, in the Count_Days, you use if month1 ==2 on the first line, and then if month1 ==12 on the 5th line. This is redundant or perhaps even a mistake. The first if will not allow the following if to be True by design.

Commented Aug 11, 2021 at 8:02

For calculating dates and times, there are several options but I will write the simple way:

from datetime import timedelta, datetime, date import dateutil.relativedelta # current time date_and_time = datetime.now() date_only = date.today() time_only = datetime.now().time() # calculate date and time result = date_and_time - timedelta(hours=26, minutes=25, seconds=10) # calculate dates: years (-/+) result = date_only - dateutil.relativedelta.relativedelta(years=10) # months result = date_only - dateutil.relativedelta.relativedelta(months=10) # week results = date_only - dateutil.relativedelta.relativedelta(weeks=1) # days result = date_only - dateutil.relativedelta.relativedelta(days=10) # calculate time result = date_and_time - timedelta(hours=26, minutes=25, seconds=10) result.time() 
answered Jan 31, 2018 at 10:53 Gavriel Cohen Gavriel Cohen 4,593 36 36 silver badges 41 41 bronze badges

There is also a datetime.toordinal() method that was not mentioned yet:

import datetime print(datetime.date(2008,9,26).toordinal() - datetime.date(2008,8,18).toordinal()) # 39 

date. toordinal()

Return the proleptic Gregorian ordinal of the date, where January 1 of year 1 has ordinal 1. For any date object d, date.fromordinal(d.toordinal()) == d .

Seems well suited for calculating days difference, though not as readable as timedelta.days .

answered Jun 9, 2019 at 14:03 Dmitriy Work Dmitriy Work 933 11 11 silver badges 19 19 bronze badges

There are cases in which this approach wins. For example, the actual difference between 2019-07-09 23:50 and 2019-07-10 00:10 is twenty minutes. (d1 - d0).days returns 0 , d1.toordinal() - d0.toordinal() returns 1 . Depends on what you need in your actual usecase.

Commented Jul 10, 2019 at 8:52

this approach can actually compare datetime and date. For example to check if 2020-04-17 == 2020-04017 00:00:00

Commented Apr 17, 2020 at 1:04
from datetime import date def d(s): [month, day, year] = map(int, s.split('/')) return date(year, month, day) def days(start, end): return (d(end) - d(start)).days print days('8/18/2008', '9/26/2008') 

This assumes, of course, that you've already verified that your dates are in the format r'\d+/\d+/\d+' .

answered Apr 15, 2016 at 14:50 Parthian Shot Parthian Shot 1,412 1 1 gold badge 14 14 silver badges 24 24 bronze badges This adds nothing new compared to the answers given 8 years earlier. -1. Commented Jun 26, 2017 at 23:17

The main difference is most of the other answers didn't even bother to account for the fact that the OP had his dates as strings. And those who did account for that largely used more complicated formatters than strictly necessary. So, the main difference is map(int, s.split('/')) . Not exactly groundbreaking, but then again this question is pretty stupid basic. My answer just shows another way to skin the cat.

Commented Jun 28, 2017 at 0:05

Also mentioned validating that dates are in the correct format, and gave a first-approximation validation regex. Which others didn't.

Commented Jun 28, 2017 at 0:07

Here are three ways to go with this problem :

from datetime import datetime Now = datetime.now() StartDate = datetime.strptime(str(Now.year) +'-01-01', '%Y-%m-%d') NumberOfDays = (Now - StartDate) print(NumberOfDays.days) # Starts at 0 print(datetime.now().timetuple().tm_yday) # Starts at 1 print(Now.strftime('%j')) # Starts at 1 
answered Mar 20, 2018 at 13:29 Antoine Thiry Antoine Thiry 2,432 4 4 gold badges 30 30 silver badges 45 45 bronze badges

If you want to code the calculation yourself, then here is a function that will return the ordinal for a given year, month and day:

def ordinal(year, month, day): return ((year-1)*365 + (year-1)//4 - (year-1)//100 + (year-1)//400 + [ 0,31,59,90,120,151,181,212,243,273,304,334][month - 1] + day + int(((year%4==0 and year%100!=0) or year%400==0) and month > 2)) 

This function is compatible with the date.toordinal method in the datetime module.

You can get the number of days of difference between two dates as follows:

print(ordinal(2021, 5, 10) - ordinal(2001, 9, 11)) 
answered May 10, 2021 at 16:29 343k 35 35 gold badges 266 266 silver badges 311 311 bronze badges

If you don't have a date handling library (or you suspect it has bugs in it), here's an abstract algorithm that should be easily translatable into most languages.

Perform the following calculation on each date, and then simply subtract the two results. All quotients and remainders are positive integers.

Step A. Start by identifying the parts of the date as Y (year), M (month) and D (day). These are variables that will change as we go along.

Step B. Subtract 3 from M

(so that January is -2 and December is 9).

Step C. If M is negative, add 12 to M and subtract 1 from the year Y.

(This changes the "start of the year" to 1 March, with months numbered 0 (March) through 11 (February). The reason to do this is so that the "day number within a year" doesn't change between leap years and ordinary years, and so that the "short" month is at the end of the year, so there's no following month needing special treatment.)

Step D. Divide M by 5 to get a quotient Q₁ and remainder R₁. Add Q₁ × 153 to D. Use R₁ in the next step.

(There are 153 days in every 5 months starting from 1 March.)

Step E. Divide R₁ by 2 to get a quotient Q₂ and ignore the remainder. Add R₁ × 31 - Q₂ to D.

(Within each group of 5 months, there are 61 days in every 2 months, and within that the first of each pair of months is 31 days. It's safe to ignore the fact that Feb is shorter than 30 days because at this point you only care about the day number of 1-Feb, not of 1-Mar the following year.)

Steps D & E combined - alternative method

Before the first use, set L=[0,31,61,92,122,153,184,214,245,275,306,337]

(This is a tabulation of the cumulative number of days in the (adjusted) year before the first day of each month.)

Add L[M] to D.

Step F Skip this step if you use Julian calendar dates rather than Gregorian calendar dates; the change-over varies between countries, but is taken as 3 Sep 1752 in most English-speaking countries, and 4 Oct 1582 in most of Europe.

You can also skip this step if you're certain that you'll never have to deal with dates outside the range 1-Mar-1900 to 28-Feb-2100, but then you must make the same choice for all dates that you process.

Divide Y by 100 to get a quotient Q₃ and remainder R₃. Divide Q₃ by 4 to get another quotient Q₄ and ignore the remainder. Add Q₄ + 36524 × Q₃ to D.

Assign R₃ to Y.

Step G. Divide the Y by 4 to get a quotient Q₅ and ignore the remainder. Add Q₅ + 365 × Y to D.

Step H. (Optional) You can add a constant of your choosing to D, to force a particular date to have a particular day-number.

Do the steps A~G for each date, getting D₁ and D₂.

Step I. Subtract D₁ from D₂ to get the number of days by which D₂ is after D₁.

Lastly, a comment: exercise extreme caution dealing with dates prior to about 1760, as there was not agreement on which month was the start of the year; many places counted 1 March as the new year.

answered Jun 30, 2022 at 21:51 Martin Kealey Martin Kealey 673 3 3 silver badges 15 15 bronze badges This just gets a plus for interest. Commented Sep 1, 2023 at 10:14

Without using datetime object in python.

# A date has day 'd', month 'm' and year 'y' class Date: def __init__(self, d, m, y): self.d = d self.m = m self.y = y # To store number of days in all months from # January to Dec. monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ] # This function counts number of leap years # before the given date def countLeapYears(d): years = d.y # Check if the current year needs to be considered # for the count of leap years or not if (d.m  
32.9k 33 33 gold badges 112 112 silver badges 170 170 bronze badges answered Jul 26, 2020 at 3:00 Abhishek Kulkarni Abhishek Kulkarni 3,770 9 9 gold badges 36 36 silver badges 43 43 bronze badges

-1: Untested code. dt = Date(01, 01, 2019 ) SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers. Even if I fixed that error, IndexError was thrown.

Commented Jan 24, 2021 at 13:58

If you want to have a date object for every calendar day between a start and end point then this code may help. It returns a date object for every day between start and end:

from math import ceil from datetime import date, datetime, timedelta def day_range(start: datetime, end: datetime) -> date: first_day = start.replace(hour=0, minute=0, second=0, microsecond=0) daycount = ceil((end - first_day) / timedelta(days=1)) for n in range(daycount): yield (start + timedelta(days=n)).date() start = datetime(2023, 1, 1, 23, 0) end = datetime(2023, 1, 4, 0, 20) for day in day_range(start, end): print(f"Day: ") 
answered Jun 16, 2023 at 13:16 Michael Busch Michael Busch

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Commented Jun 17, 2023 at 1:55

If the dates are datetime.date objects, then a simple subtraction along with timedelta.days to get the difference in days work well.

from datetime import date date1 = date(2023, 8, 18) date2 = date(2024, 8, 19) diff1 = date2 - date1 # datetime.timedelta(days=367) diff1.days # 367 diff2 = date1 - date2 # datetime.timedelta(days=-367) diff2.days # -367 

However, if the dates are datetime.datetime objects, it is not as straightforward because .days rounds down no matter if the difference is positive or negative.

For example, in the following example, the time difference between the two datetimes is 5 hours and if we use timedelta.days to get the number of days, that difference becomes 0 days or -1 day depending on which datetime was subtracted from which. Given the difference is less than 24 hours, this difference should probably be 0 days.

To get the same absolute value no matter which direction the subtraction happens, we can get the timedelta in total seconds and convert that number into number of days by dividing it by 24*3600 (total number of seconds in a day) and convert to an integer.

from datetime import datetime date1 = datetime(2024, 8, 18, 12, 0, 0) # 2024-08-18 12:00:00 date2 = datetime(2024, 8, 18, 17, 0, 0) # 2024-08-18 17:00:00 positive_diff = date2 - date1 # datetime.timedelta(seconds=18000) positive_diff.days # 0 negative_diff = date1 - date2 # datetime.timedelta(days=-1, seconds=68400) negative_diff.days # -1 diff_in_days1 = int(positive_diff.total_seconds() / (24*3600)) # 0 diff_in_days2 = int(negative_diff.total_seconds() / (24*3600)) # 0