🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.c.moderated
Article #2310

Re: BEST date <=> daynum converter?

#2310
From: Kevin Miller
Date: Sat, 16 Mar 1996 17:39
86 lines
4281 bytes
heading_anthony@jpmorgan.com (Anthony Heading) writes:

>  What's the speediest algorithm for conversion between day-month-year
>dates and "days since 1janXX"?  I'd like to find something really fast
>which only need cope with dates between say 1970 and 2100.

>One rather nice thing I found was the method ascribed to Fliegel
>and Van Flandern (CACM 1968); an (untested) implementation attached.
>It avoids using floating point, which is nice.  Many other routines
>seem to, but I always worry about doing essentially discrete maths with
>floats.  Is that paranoid?  
 
Using floating-point arithmetic for this problem would be idiotic.  
The inputs and outputs are inherently integral, and floating-point 
arithmetic is not as standardized as integer arithmetic.  

>But perhaps the lack of any conditionals below is excessive.  There must
>be something faster/simpler.

>Any thoughts?

How about the following?  On a DEC-Station 5000 it was able to 
convert 72,684 dates in about one second, as timed by my wristwatch.  
That is all the dates there are in the 199-year time span to which 
it can be applied.  
 
/* --------------------------------------------------------------------- */ 
 
/*   DEFINITION OF DayOrd   */ 
 
/*   This function returns the ordinal number corresponding to a given   */ 
/*   date between January 1, 1901 and December 31, 2099, inclusive.      */ 
/*   The ordinal number is defined to 1 for January 1, 1901, and         */ 
/*   increases by 1 each day thereafter.  If the date is not in the      */ 
/*   range given above, the function returns -1 as an error code.        */ 
/*   It assumes the calendar in use is the Gregorian, which is the       */ 
/*   calendar in general use in America and western Europe in the        */ 
/*   twentieth century.  The algorithm will not work without             */ 
/*   modification outside the range of years given above, due to the     */ 
/*   fact that three out of every four century years are not leap        */ 
/*   years.                                                              */ 

long int DayOrd (int Year, int Month, int Day) {
 
   const static int S [] = {-31,
                            0,
                            31,
                            31+28,
                            31+28+31,
                            31+28+31+30,
                            31+28+31+30+31,
                            31+28+31+30+31+30,
                            31+28+31+30+31+30+31,
                            31+28+31+30+31+30+31+31,
                            31+28+31+30+31+30+31+31+30,
                            31+28+31+30+31+30+31+31+30+31,
                            31+28+31+30+31+30+31+31+30+31+30,
                            31+28+31+30+31+30+31+31+30+31+30+31};

   int L;
   long int A, N;

   if (Year < 1901 || Year > 2099) return -1;

   A = Year - 1900;
   L = Month <= 2 && ! (A%4);
   N = 365 * (A - 1) + (A/4) - L + S[Month] + Day;

   return N; }
 
/* --------------------------------------------------------------------- */ 

This algorithm is very easy to understand and maintain.  It is obvious 
where all of the numbers come from.  On any decent compiler, the work 
of adding up the number of days in the first n months will be done at 
compile time.  I had no trouble modifying this so it would work for 
all years from the beginning of the Gregorian calendar (sixteenth 
century, I believe) up to any year for which the answer can be held 
in a "long int", but that would make it a little slower, so I am 
posting this form given here.  
 
The algorithm you posted by Fliegel and Van Flandern looks very 
clever, but it also looks like it would be very hard to understand.  
 
               - Kevin Jay Miller 
 ` 
Technical Details
Message-ID: <4ieud4$b9f@solutions.solon.com>
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
References: <4hv04d$j80@solutions.solon.com>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!solon.com!not-for-mail
From: kjm@sbphy.physics.ucsb.edu ( Kevin Miller)
Newsgroups: comp.lang.c.moderated
Subject: Re: BEST date <=> daynum converter?
Date: 16 Mar 1996 11:39:48 -0600
Organization: University of California, Santa Barbara
Sender: clc@solutions.solon.com
Approved: clc@solutions.solon.com
Message-ID: <4ieud4$b9f@solutions.solon.com>
References: <4hv04d$j80@solutions.solon.com>
NNTP-Posting-Host: solutions.solon.com