date calculation algorithms
TRANSCRIPT
Data Calculation Algorithms
Summary:
Survey of some old techniques of calculating dates in Y2K projects.
Date Calculation Algorithms
These algorithms should be implemented using 32-bit or 9-digit precision arithmetic in the
computer language of your choice. All division is integer division, i.e. you drop the remainder.
For example, 35/4 is 8; to make this clear, the algorithms use the INT function, INT(35/4). These
algorithms make use of the MOD function, the remainder after integer division.
The following algorithms are included.
Convert from YYYY.MM.DD to YYYY.NNN and determine day-of-week
Input: YYYY, MM, DD
Output: NNN (1-366), DOW (0-6 where 0=Sunday)
/* LY = leap year indicator */
if MOD(YYYY,4) = 0 then LY = 1 else LY = 0
if MOD(YYYY,100) = 0 then LY = 0
if MOD(YYYY,400) = 0 then LY = 1
NNN = INT(((MM + 2) * 3055) / 100) + DD – 91
if NNN > (59 + LY) then NNN = NNN – 2 + LY
T = INT(YYYY / 100) – 6 - INT(YYYY / 400)
DOW = MOD((NNN + INT(YYYY * 5) / 4) – LY – T), 7)
Example 1996, Nov 1 => NNN = 306 and DOW = 5
Convert from YYYY.NNN to YYYY.MM.DD and determine day-of-week
Input: YYYY.NNN (N= 1 – 366)
Output: YYYY, MM, DD, DOW (0-6 where 0=Sunday)
/* LY = leap year indicator */
if MOD(YYYY,4) = 0 then LY = 1 else LY = 0
if MOD(YYYY,100) = 0 then LY = 0
if MOD(YYYY,400) = 0 then LY = 1
WORK = NNN
if WORK > (LY + 59) then WORK = WORK + 2 - LY
MM = INT(((WORK + 91) * 100) / 3055)
DD = (WORK + 91) – INT((MM * 3055) / 100)
MM = MM – 2
T = INT(YYYY / 100) – 6 – INT(YYYY / 400)
DOW = MOD((NNN + INT(YYYY * 5) / 4) – LY – T), 7)
Example 1996, 306 => NNN = 1996 Nov 1 and DOW = 5
Convert from YYYY.NNN to Lilian (day 1 = Fri Oct 15, 1582)
Input: YYYY.NNN (N= 1 – 366)
Output: Lilian
LIL = INT(((YYYY - 1201) * 36525) / 100 ) – 139444 + NNN
– INT((YYYY – 1201)/100)
+ INT((YYYY – 1201) / 400)
Example 1996, 306 => Lilian = 151229
Convert from Lilian to YYYY.NNN
Input: Lilian
Output: YYYY.NNN (N= 1 – 366)
CLD = INT(((LIL + 139444) * 100) / 3652425)
NNN = CLD + LIL + 139444 – INT(CLD/4)
WORK = INT((NNN * 100)/36525)
if MOD((NNN * 100), 36525) = 0 then WORK = WORK - 1
NNN = NNN - INT((WORK * 36525)/100)
YYYY = WORK + 1201
Example 151229 => 1996.306
Convert from Lilian to day-of-week
Input: Lilian
Output: DOW (0-6, 0 = Sunday)
DOW = MOD((LIL + 4), 7)
Example 151229 => 1996.306 => DOW = 5
Convert from YYYY.MM.DD to YYYY.NNN
Input: YYYY, MM, DD
Output: NNN (1-366), DOW (0-6 where 0=Sunday)
/* LY = leap year indicator */
if MOD(YYYY,4) = 0 then LY = 1 else LY = 0
if MOD(YYYY,100) = 0 then LY = 0
if MOD(YYYY,400) = 0 then LY = 1
NNN = INT(3/(MM + 1)) * (31 * (MM - 1) + DD)
+ INT((MM + 9)/12)
* (INT(((305 * (MM – 1) – 15) + INT((MM + 3)/12) * 5 * INT(18/MM))/10) + DD + LY)
Example 1996, Nov 1 => NNN = 306
Convert from YYYY.MM.DD to day-of-week
Input: YYYY, MM, DD
Output: DOW (0-6, 0 = Sunday)
WDD = DD
if MM < 3
then (WMM = MM +12, WYYYY = YYYY – 1) else (WMM = MM, WYYYY = YYYY)
DOW = MOD((WDD + 1 + (WMM * 2)
+ INT(((WMM + 1) * 3)/5)
+ WYYYY + INT(WYYYY/4)
– INT(WYYYY/100)
+ INT(WYYYY/400)), 7)
Example 1996, Nov 1 => DOW = 5