# 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?

78

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

The relevant section of the docs: https://docs.python.org/library/datetime.html.

See this answer for another example.

Tuesday, June 1, 2021

74

Here's an easy way:

``````\$depart = strtotime(implode(' ', \$_POST['departon']));
\$return = strtotime(implode(' ', \$_POST['returnon']));

\$diff = floor((\$return - \$depart) / (60 * 60 * 24));
``````

Note: there's only 30 days in June.

Wednesday, March 31, 2021

42

http://momentjs.com/ or https://date-fns.org/

From Moment docs:

``````var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days')   // =1
``````

or to include the start:

``````a.diff(b, 'days')+1   // =2
``````

Beats messing with timestamps and time zones manually.

Depending on your specific use case, you can either

1. Use `a/b.startOf('day')` and/or `a/b.endOf('day')` to force the diff to be inclusive or exclusive at the "ends" (as suggested by @kotpal in the comments).
2. Set third argument `true` to get a floating point diff which you can then `Math.floor`, `Math.ceil` or `Math.round` as needed.
3. Option 2 can also be accomplished by getting `'seconds'` instead of `'days'` and then dividing by `24*60*60`.
Wednesday, June 9, 2021

12

One way is to extract the hour and convert minutes to hours.

There should be no need to convert to / from strings.

``````import pandas as pd

idx = pd.DatetimeIndex(['2016-01-01 00:30:00',
'2016-01-01 01:00:00',
'2016-01-01 01:30:00'],
dtype='datetime64[ns]', name='date_time', freq=None)

idx.hour + idx.minute / 60

# Float64Index([0.5, 1.0, 1.5], dtype='float64', name='date_time')
``````
Tuesday, August 24, 2021

22

The issue you are coming up against comes from the fact that `datetime.datetime(2012, 10, 31, 0, 0)` is the 31st of the month, and not all months have a 31st. Since the `rrule` module is an implementation of RFC 2445. Per RFC 3.3.10:

Recurrence rules may generate recurrence instances with an invalid date (e.g., February 30) or nonexistent local time (e.g., 1:30 AM on a day where the local time is moved forward by an hour at 1:00 AM). Such recurrence instances MUST be ignored and MUST NOT be counted as part of the recurrence set.

Since you have a monthly rule that generates the 31st of a month, it will skip all months with 30 or fewer days. You can see this bug report in `dateutil` about this issue.

If you just want the last day of the month, you should use the `bymonthday=-1` argument:

``````from dateutil.rrule import rrule, MONTHLY
from datetime import datetime

disclosure_start_date = datetime(2012, 10, 31, 0, 0)

rr = rrule(freq=MONTHLY, dtstart=disclosure_start_date, bymonthday=-1)
# >>>rr.between(datetime(2013, 1, 1), datetime(2013, 5, 1))
# [datetime.datetime(2013, 1, 31, 0, 0),
#  datetime.datetime(2013, 2, 28, 0, 0),
#  datetime.datetime(2013, 3, 31, 0, 0),
#  datetime.datetime(2013, 4, 30, 0, 0)]
``````

Unfortunately, I don't think there's an RFC-compliant way to generate a simple RRULE that just falls back to the end of the month if-and-only-if it's necessary (e.g. what do you do with January 30th - you need fallback for February, but you don't want to use `bymonthday=-2` because that will give you Feb. 27th, etc).

Alternatively, for a simple monthly rule like this, a better option is probably to just use `relativedelta`, which does fall back to the end of the month:

``````from dateutil.relativedelta import relativedelta
from datetime import datetime

def disclosure_dates(dtstart, rd, dtend=None):
ii = 0
while True:
cdate = dtstart + ii*rd
ii += 1

yield cdate
if dtend is not None and cdate >= dtend:
break

dtstart = datetime(2013, 1, 31, 0, 0)
rd = relativedelta(months=1)
rr = disclosure_dates(dtstart, rd, dtend=datetime(2013, 5, 1))

# >>> list(rr)
# [datetime.datetime(2013, 1, 31, 0, 0),
#  datetime.datetime(2013, 2, 28, 0, 0),
#  datetime.datetime(2013, 3, 31, 0, 0),
#  datetime.datetime(2013, 4, 30, 0, 0),
#  datetime.datetime(2013, 5, 31, 0, 0)]
``````

Note that I specifically used `cdate = dtstart + ii * rd`, you do not want to just keep a "running tally", as that will pin to the shortest month the tally has seen:

``````dt_base = datetime(2013, 1, 31)
dt = dt_base
for ii in range(5):
cdt = dt_base + ii*rd
print('{} | {}'.format(dt, cdt))
dt += rd
``````

Result:

``````2013-01-31 00:00:00 | 2013-01-31 00:00:00
2013-02-28 00:00:00 | 2013-02-28 00:00:00
2013-03-28 00:00:00 | 2013-03-31 00:00:00
2013-04-28 00:00:00 | 2013-04-30 00:00:00
2013-05-28 00:00:00 | 2013-05-31 00:00:00
``````
Tuesday, October 19, 2021