230

I have two different dates and I want to know the difference in days between them. The format of the date is YYYY-MM-DD.

I have a function that can ADD or SUBTRACT a given number to a date:

def addonDays(a, x):
   ret = time.strftime("%Y-%m-%d",time.localtime(time.mktime(time.strptime(a,"%Y-%m-%d"))+x*3600*24+3600))      
   return ret

where A is the date and x the number of days I want to add. And the result is another date.

I need a function where I can give two dates and the result would be an int with date difference in days.

codeforester
  • 39,467
  • 16
  • 112
  • 140
mauguerra
  • 3,728
  • 5
  • 31
  • 37

7 Answers7

445

Use - to get the difference between two datetime objects and take the days member.

from datetime import datetime

def days_between(d1, d2):
    d1 = datetime.strptime(d1, "%Y-%m-%d")
    d2 = datetime.strptime(d2, "%Y-%m-%d")
    return abs((d2 - d1).days)
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 62
    Great answer. To be clear, the result of `(d2 - d1)` will be a [`timedelta`](http://docs.python.org/library/datetime.html#datetime.timedelta) object. – aganders3 Dec 07 '11 at 17:24
  • 1
    I have this error on the console: type object 'datetime.datetime' has no attribute 'strptime' – mauguerra Dec 07 '11 at 18:00
  • 3
    I get TypeError: 'int' object is not callable when I try to do .days() on a timedelta object and the documentation makes not mention of it either (https://docs.python.org/2/library/datetime.html). – Reddspark Jun 26 '17 at 10:46
  • 8
    Could you please mention [`total_seconds`](https://docs.python.org/3/library/datetime.html#datetime.timedelta.total_seconds), too? I think it is important as it is what I expected to get when I tried `seconds` without reading the docs. – Martin Thoma Aug 10 '17 at 14:10
  • @MartinThoma It works when I tried `return abs((d2 - d1).seconds)`. :) – agent18 Mar 06 '18 at 07:49
  • 1
    @ThejKiran Make d2 and d1 be apart exactly one day and see if it is what you expect ;-) – Martin Thoma Mar 06 '18 at 08:06
  • to have datetime of file creation, i use `datetime.fromtimestamp(os.path.getctime(file))` – Lei Yang Jul 23 '19 at 09:31
  • Note that a `timedelta` only stores days, seconds, and microseconds. All other periods, e.g. hours, require conversion by hand, and the values may be of type `float` for partial values – simpleuser Sep 05 '19 at 20:10
  • 1
    @MartinThoma I was starting to think there was a bug in the library. The limits on the `seconds` attribute should have been a red flag. – Christian Pao. Jan 21 '21 at 14:38
  • 1
    @Christian One thing to mention here is that you can **divide by unit**, e.g.: `(datetime(2020, 1, 1, 12, 0) - datetime(2020, 1, 3, 12, 0)) / timedelta(days=1)` gives `-2.0` and `(datetime(2020, 1, 1, 12, 0) - datetime(2020, 1, 3, 12, 0)) / timedelta(seconds=1)` gives `-172800.0`. That is probably the cleanest way to do it. – Martin Thoma Jan 21 '21 at 15:48
  • for whom do not want abs for diff. – Ziu May 09 '21 at 17:42
48

Another short solution:

from datetime import date

def diff_dates(date1, date2):
    return abs(date2-date1).days

def main():
    d1 = date(2013,1,1)
    d2 = date(2013,9,13)
    result1 = diff_dates(d2, d1)
    print '{} days between {} and {}'.format(result1, d1, d2)
    print ("Happy programmer's day!")

main()
0x8BADF00D
  • 7,138
  • 2
  • 41
  • 34
  • 3
    Isn't the `if` in the `diff_dates` function completely unnecessary? By the definition of the absolute value, `abs(date1-date2)` will always be equal to `abs(date2-date1)`. – Blckknght Jun 30 '14 at 07:17
  • At least with Python3.5 the print statement should look like this: print ('{} days between {} and {}'.format(result1, d1, d2)) – Ernestas Kardzys Nov 23 '17 at 10:50
10

You can use the third-party library dateutil, which is an extension for the built-in datetime.

Parsing dates with the parser module is very straightforward:

from dateutil import parser

date1 = parser.parse('2019-08-01')
date2 = parser.parse('2019-08-20')

diff = date2 - date1

print(diff)
print(diff.days)

Answer based on the one from this deleted duplicate

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
6

I tried the code posted by larsmans above but, there are a couple of problems:

1) The code as is will throw the error as mentioned by mauguerra 2) If you change the code to the following:

...
    d1 = d1.strftime("%Y-%m-%d")
    d2 = d2.strftime("%Y-%m-%d")
    return abs((d2 - d1).days)

This will convert your datetime objects to strings but, two things

1) Trying to do d2 - d1 will fail as you cannot use the minus operator on strings and 2) If you read the first line of the above answer it stated, you want to use the - operator on two datetime objects but, you just converted them to strings

What I found is that you literally only need the following:

import datetime

end_date = datetime.datetime.utcnow()
start_date = end_date - datetime.timedelta(days=8)
difference_in_days = abs((end_date - start_date).days)

print difference_in_days
schalkneethling
  • 6,327
  • 3
  • 21
  • 20
  • 1
    My code uses `datetime.strptime` to convert strings to `datetime` objects. Since the OP stated that "The format of the date is YYYY-MM-DD", I assumed the dates were represented as strings. If they're not, there's obviously no need for a conversion. – Fred Foo May 15 '13 at 11:41
2

Try this:

data=pd.read_csv('C:\Users\Desktop\Data Exploration.csv')
data.head(5)
first=data['1st Gift']
last=data['Last Gift']
maxi=data['Largest Gift']
l_1=np.mean(first)-3*np.std(first)
u_1=np.mean(first)+3*np.std(first)


m=np.abs(data['1st Gift']-np.mean(data['1st Gift']))>3*np.std(data['1st Gift'])
pd.value_counts(m)
l=first[m]
data.loc[:,'1st Gift'][m==True]=np.mean(data['1st Gift'])+3*np.std(data['1st Gift'])
data['1st Gift'].head()




m=np.abs(data['Last Gift']-np.mean(data['Last Gift']))>3*np.std(data['Last Gift'])
pd.value_counts(m)
l=last[m]
data.loc[:,'Last Gift'][m==True]=np.mean(data['Last Gift'])+3*np.std(data['Last Gift'])
data['Last Gift'].head()
Ryan
  • 1,972
  • 2
  • 23
  • 36
-2

I tried a couple of codes, but end up using something as simple as (in Python 3):

from datetime import datetime
df['difference_in_datetime'] = abs(df['end_datetime'] - df['start_datetime'])

If your start_datetime and end_datetime columns are in datetime64[ns] format, datetime understands it and return the difference in days + timestamp, which is in timedelta64[ns] format.

If you want to see only the difference in days, you can separate only the date portion of the start_datetime and end_datetime by using (also works for the time portion):

df['start_date'] = df['start_datetime'].dt.date
df['end_date'] = df['end_datetime'].dt.date

And then run:

df['difference_in_days'] = abs(df['end_date'] - df['start_date'])
-5

pd.date_range('2019-01-01', '2019-02-01').shape[0]

ar91
  • 9
  • 1