Converting a Date to a date_t


Many of my date functions use parameters of type date_t, which is a long representing days elapsed since 1 January, 0001 A.D. This conversion occurs in three stages. First, all years previous to the current year must be converted into the days elapsed since 1 January, 0001 A.D. Function years_to_days (Listing 1) calculates this value by following the rules that determine leap years. Since there are always at least 365 days in a year, years_to_days multiples the year value (current year -1) by 365. It then adds the result of this operation to (year value) divided by 4 to account for leap years. Next, years_to_days subtracts (year value) divided by 100 to account for the century years which are not leap years. Finally, years_to_days adds (year value) divided by 400 to add back the centuries which were leap years. Thus, the formula is:

date_value = year * 365 + year / 4 - year / 100 + year / 400;
Users typically enter dates in terms of years, months, and days; these dates must be converted to type date_t before the date functions can use them. This value presumes the Gregorian Calendar in use today was implemented on 1 January, 0001 A.D., (which of course, it was not) and totally ignores the adjustments made by Pope Gregory in 1582 to the calendar. Ignoring this adjustment invalidates all calculations for dates prior to October of 1582, but works for later dates, since days elapsed merely serves as an index — its absolute value is not important.

In the second step, function months_to_days (Listing 1) uses a lookup table to convert all months prior to the current month into elapsed days. These days must be added to the value obtained in the first step. The final step is to simply add the current day of month to the value obtained from the first two steps.

Using this scheme, a huge range of dates is possible; however, I have imposed an artificial upper limit of 31 December, 9999 (which falls on a Friday).