Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!nbires!vianet!devine From: devine@vianet.UUCP (Bob Devine) Newsgroups: comp.lang.c Subject: Calculating the length of a year Message-ID: <53@vianet.UUCP> Date: Tue, 11-Nov-86 22:46:36 EST Article-I.D.: vianet.53 Posted: Tue Nov 11 22:46:36 1986 Date-Received: Wed, 12-Nov-86 20:19:10 EST Organization: ViaNetix Boulder, CO. Lines: 68 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.