[comp.lang.c] Calculating the length of a year

devine@vianet.UUCP (Bob Devine) (11/12/86)

  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.

stuart@bms-at.UUCP (Stuart D. Gathman) (11/13/86)

In article <53@vianet.UUCP>, devine@vianet.UUCP (Bob Devine) writes:

>     2. Gregorian rules -- this works from the year after your country

> 	   if (year%4 == 0 && year%100 != 0 || year%400 == 0)

The years 4000, 8000, . . . are not leap years!
-- 
Stuart D. Gathman	<..!seismo!{vrdxhq|dgis}!bms-at!stuart>

devine@vianet.UUCP (Bob Devine) (11/14/86)

In article <267@bms-at.UUCP>, stuart@bms-at.UUCP (Stuart D. Gathman) writes:
> The years 4000, 8000, . . . are not leap years!

  I, too, was certain that I had read years divisible by 4000 are
not leap years.  However, after several people replied with "are
you really sure?" letters, I checked.  My findings were that it is
likely that someone did once make that suggestion but it has never
been formally agreed to.  I never found my recollected source.

  While it is true that the Gregorian rule results in not quite a
tropical year (see a previous posting by me, or send mail for info)
it is entirely acceptable for the next 1000 years.  Who knows what
will happen in that millenium.

Bob Devine

weemba@brahms (Matthew P Wiener) (11/15/86)

Summary:

Expires:

Sender:

Followup-To:

Distribution:

Keywords:


In article <54@vianet.UUCP> devine@vianet.UUCP (Bob Devine) writes:
>While it is true that the Gregorian rule results in not quite a tropical
>year it is entirely acceptable for the next 1000 years.

Not if you are Greek Orthodox!  For them, the year 2900 is not a leap year.

ucbvax!brahms!weemba	Matthew P Wiener/UCB Math Dept/Berkeley CA 94720

roy@gitpyr.gatech.EDU (Roy Mongiovi) (11/16/86)

In article <54@vianet.UUCP>, devine@vianet.UUCP (Bob Devine) writes:
> In article <267@bms-at.UUCP>, stuart@bms-at.UUCP (Stuart D. Gathman) writes:
> > The years 4000, 8000, . . . are not leap years!
> 
>   I, too, was certain that I had read years divisible by 4000 are
> not leap years.  However, after several people replied with "are
> you really sure?" letters, I checked.  My findings were that it is
> likely that someone did once make that suggestion but it has never
> been formally agreed to.  I never found my recollected source.

In the book "ASTRONOMY" by Franklyn M. Branley (Astronomer Emeritus,
The American Museum - Hayden Planetarium), Mark R. Chartrand III
(Chairman, The American Museum - Hayden Planetarium), and Helmut
K. Wimmer (Art Supervisor, The American Museum - Hayden Planetarium),
on page 412 while discussing the Gregorian Calendar it states:

	"At the present time the intercalation procedure is as follows:
	 all years divisible by 4 are leap years, except century years
	 which are leap years only when divisible by 400.  Exceptions
	 are the years 4000, 8000, 12 000, and so on, which are not
	 leap years."

I would have thought that the authors would have known if the "multiple
of 4000" rule had not been adopted, but who knows.  Where is this sort
of thing "officially" recorded?
-- 
Roy J. Mongiovi		Systems Analyst		Office of Computing Services
Georgia Institute of Technology		Atlanta GA  30332.	(404) 894-4660
 ...!{akgua, allegra, amd, hplabs, ihnp4, masscomp, ut-ngp}!gatech!gitpyr!roy

stuart@bms-at.UUCP (Stuart D. Gathman) (11/18/86)

In article <54@vianet.UUCP>, devine@vianet.UUCP (Bob Devine) writes:

>   I, too, was certain that I had read years divisible by 4000 are

I read this in the Encyclopedia Brittanica under 'calendar'.
-- 
Stuart D. Gathman	<..!seismo!{vrdxhq|dgis}!bms-at!stuart>

steve@jplgodo.UUCP (Steve Schlaifer x43171 301/167) (11/19/86)

In the Explanatory Supplement to the Astronomical Ephemeris and American
Ephemeris and Nautical Almanac, page 412, Section 14C,

	"The Gregorian reform of the Julian calendar consisted of:

	(i) ommitting 10 days from the calendar reckoning, the day next after 
	1582 October 4 being designated 1582 October 15, for the purpose of 
	restoring the date of the actual vernal equinox to March 21;

	(ii) adopting a different rule for leap year, by omitting the 
	intercalary day in centurial years that are not divisible by 400, such
	as 1700, 1800, 1900, and 2100, in order to correct the error of the
	Julian calendar where an intercalary day is inserted every four years;

	(iii) fixing rules for determining the date of Easter in the revised
	calendar.

	The mean length of the Gregorian calendar year is 365.2425 days.  At
	the completion of a 400-year calendar cycle, the cumulative discrepancy
	with the tropical year is only a few hours."

[ Note that there is no mention of any further correction; just a note that
there is a small cumulative error. -rss ]

Later, on page 413, the Explanatory Supplement notes that

	"At a meeting of a Congress of the Orthodox Oriental Churches held in
	Constantinople in May, 1923, the Julian calendar was replaced by a
	modified Gregorian calendar in which century years are leap years only
	when division of the century number by 9 leaves a remainder of either
	2 or 6, and Easter is determined by the astronomical Moon for the
	meridian of Jerusalem; see Milankovitch (Milankovitch, M. Das Ende
	des julianischen Kalenders und der neue Kalender der orientalischen
	Kirchen. _Ast. Nach._, *220*, 379-384, 1924).

Note that this was long after Europe, the British colonies (including what
became the U.S. and Canada), and, I presume, the Spanish and Portugese colonies
had already adopted the unmodified Gregorian calendar and was only adopted by
the Orthodox Oriental Churches (Greek Orthodox) as near as I can tell.
-- 

...smeagol\			Steve Schlaifer
......wlbr->!jplgodo!steve	Advance Projects Group, Jet Propulsion Labs
....logico/			4800 Oak Grove Drive, M/S 301/165
				Pasadena, California, 91109
					+1 818 354 3171