Calculating the length of a year

Bob Devine devine at vianet.UUCP
Wed Nov 12 13:46:36 AEST 1986


  Several weeks back I promised that I would provide the necessary
functions to give the historical correct length of a year over a wide
range of years.  The code has been submitted to mod.sources.

Bob Devine

-----
[ Here's part of the READ_ME file:]

  This collection of functions attempts to provide the number of
days in a year based upon a selected year and country.  It is
being posted because of a promise I made to the readers of net.lang.c.

  There are basically three levels of that can be used in to calculate
how long a year is:

    1. Divisibility by 4 -- this works for the years 1901-2099 and,
       as a result, is suitable for nearly all programs.  It can be
       coded as:                     or a faster version:
	   
	   if (year % 4 == 0)             if ((year & 0x03) == 0)
	       days_in_year = 366;            days_in_year = 366;
	   else                           else
	       days_in_year = 365;            days_in_year = 365;


    2. Gregorian rules -- this works from the year after your country
       adopted the Gregorian calendar through the forseeable future.
       It can be coded as:

	   if (year%4 == 0 && year%100 != 0 || year%400 == 0)
	       days_in_year = 366;
	   else
	       days_in_year = 365;

       or slightly faster (as Karl Heuer suggested to me via mail):

	   if ((year%4 == 0) && (year%100 != 0 || year%400 == 0))
	       days_in_year = 366;
	   else
	       days_in_year = 365;

       or (depending on how the remainder operator is implemented)
       this is up to 5 times faster by taking advantage of some
       common factors of 100 and 400:

	   register int ndiv100;	/* Boolean for not divisible by 100 */

	   if ((year&0x3)==0 && (ndiv100=year%100) || (year&0xF)==0 && !ndiv100)
	       days_in_year = 366;
	   else
	       days_in_year = 365;

       or even faster by using Karl Heuer's suggestion of reordering
       the expression:

	   if ((year&0x3)==0 && ((year&0xF)==0 || year%100!=0))
	       days_in_year = 366;
	   else
	       days_in_year = 365;

       I believe that this is the fastest possible check for leap years.
       Does anyone know of a fast check for remainders so that the "% 100"
       test can be speeded up?

    3. Country-dependent rules --  which is what this collection of
       functions attempt to do.  It gets messy.



More information about the Comp.lang.c mailing list