2008-08-18

Date Arithmetic

In 1996 I wrote a log file management utility on a UNISYS mainframe. It's written in SSG, an obscure script language that has no built-in date arithmetic. It worked mostly OK with my own home-cobbled date arithmetic routines, but every now and then I get complaints about it blowing up due to date-related problems. Time for correct and robust date arithmetic!

I came across these algorithms by Gary Katch. They are short, fast and easily portable. All that's required is integer arithmetic in about 32 bits.

There's no copyright notice on Gary's page, so assuming his consent I'll excerpt the bare bones here, just in case his page gets lost on the 'net:


Calculate day number from date


Given integer y, m, d, calculate day number g as:

function g(y,m,d)
m = (m + 9) % 12
y = y - m/10
return 365*y + y/4 - y/100 + y/400 + (m*306 + 5)/10 + d - 1 )

Calculate date from day number


Given day number g, calculate year, month, and day:

function d(g)
y = (10000*g + 14780)/3652425
ddd = g - (365*y + y/4 - y/100 + y/400)
if (ddd < 0) then
y = y - 1
ddd = g - (365*y + y/4 - y/100 + y/400)
endif
mi = (100*ddd + 52)/3060
mm = (mi + 2)%12 + 1
y = y + (mi + 2)/12
dd = ddd - (mi*306 + 5)/10 + 1
return y, mm, dd



In these routines, "%" means modulo, and all division is integer (and thus truncated). I've found them to work well and can recommend them.

No comments: