Subtracting two dates

Solution 1:

Dates form an affine space. This means that the result of subtracting two dates is not another date, but rather a time interval. For example, the result of subtracting January 1, 2013 from January 2, 2013, is the time interval of one day. It is not another date.

In an affine space, there are two sorts of things, called "points" and "vectors". In this case the points are dates and the vectors are intervals. If $a$ and $b$ are points, $i$ and $j$ are intervals, and $c$ is an ordinary number, then you can perform the following operations:

$$\begin{array}{cc} \text{operation} & \text{result type} \\ a - b & \text{interval}\\ a + i & \text{date}\\ a - i & \text{date}\\ i + j & \text{interval}\\ i - j & \text{interval}\\ c\cdot i & \text{interval} \end{array}$$

Note in particular that you can not add two dates.

Usually the easiest way to perform date calculations is to convert the dates to a so-called "epoch time", which is simply a number of days (or seconds) that have elapsed since some particular reference time, called the "epoch". For example, if we choose 1 January 2000 as the epoch, then 31 January 2000 is converted to the epoch date 30; 31 December 2000 is converted to the epoch date 365, and 1 January 2004 is converted to the epoch date 1461. Then to calculate the difference between two dates, one converts both to epoch dates and performs a simple subtraction.

The subtraction is easy, but the conversion may be complicated, because the calendar is complicated. For example, to find out that 31 December 2000 is epoch date 365 and not 364, one much know whether 2000 was a leap year, and then it makes a difference which calendar you are using; in some calendars 2000 is a leap year; in others it isn't.

You can figure out the conversions yourself, or you can use the algorithms from Calendrical Calculations by Dershowitz.

You asked in a comment how to find how many leap days are in an interval of 2,000 days, and the answer is that you can't, unless you know two things. First, what calendar are you using? And second, what day is the start of the interval? Different intervals of 2,000 days will include different numbers of leap days. In the epoch system, the question becomes: What date is 2,000 days after my start date $s$? Then to find the answer you convert $s$ to an epoch date, add 2,000, and convert back to a calendar date. If $s$ converts to the epoch date 16,077, then the date 2,000 days later is just 18,077; the tricky part is converting this back to a calendar date again.

The "Julian days" system mentioned by other posts in this thread is an example of an epoch system. The epoch date in that system is 1 January 4713 BCE. Depending on the details of your computer system, a Julian day system may or may not be the easiest thing to program.

Solution 2:

This is a terrible problem I faced decades ago and it was crucial not to be in any error. The easiest way has been, as suggested already by user44197, to use Julian Days. The book "Numerical Recipes" contains the full algorithm.

In the book entitled "Numerical Recipes in ??", you will find

a subroutine named JULDAY which returns the Julian Day corresponding to a date (month, day, year). Using this subroutine twice will allow you to perform date differences.

a subroutine named CALDAT which returns the date (month, day, year) from a Julian Day.

The homepage of "Numerical Recipes" is at http://www.nr.com/

At http://www.nr.com/oldverswitcher.html, you should be able to get free copies of these subroutines for the oldest versions of the book (in C or Fortran). These have been the subroutines I used for my work more than twenty years ago.