/*******************************************************/ /* leapyear.c: Ansi C source for leap year program */ /* By Terry R. McConnell */ /*******************************************************/ /* Usage: leapyear year correctly prints: year is a leap year year is not a leap year */ /* The following background information is taken from the calendar FAQ maintained by Claus Tondering. The Julian calendar has 1 leap year every 4 years: Every year divisible by 4 is a leap year. However, this rule was not followed in the first years after the introduction of the Julian calendar in 45 BC. Due to a counting error, every 3rd year was a leap year in the first years of this calendar's existence. The leap years were: 45 BC, 42 BC, 39 BC, 36 BC, 33 BC, 30 BC, 27 BC, 24 BC, 21 BC, 18 BC, 15 BC, 12 BC, 9 BC, AD 8, AD 12, and every 4th year from then on. There were no leap years between 9 BC and AD 8. This period without leap years was decreed by emperor Augustus and earned him a place in the calendar, as the 8th month was named after him. It is a curious fact that although the method of reckoning years after the (official) birthyear of Christ was not introduced until the 6th century, by some stroke of luck the Julian leap years coincide with years of our Lord that are divisible by 4. The Gregorian calendar has 97 leap years every 400 years: Every year divisible by 4 is a leap year. However, every year divisible by 100 is not a leap year. However, every year divisible by 400 is a leap year after all. */ /* Use negative numbers for years B.C. The year must be in the range -sizeof(int) < year <= sizeof(int) */ #include #include #define TRUE 1 #define FALSE 0 int GLeapYearQ(int ); /* Gregorian rule. */ int JLeapYearQ(int ); /* Julian rule. They return 1 or 0 */ int main(int argc, char **argv) { int year; if(argc <= 1){ fprintf(stderr,"Usage: leapyear year\n"); return 1; } year = atoi(*++argv); if( year >= 1582 ) /* Use Gregorian Rule */ if( GLeapYearQ(year) == TRUE ) { printf("%s is a leap year.\n",*argv); return 0; } else { printf("%s is not a leap year.\n",*argv); return 0; } /* Else use Julian Rule */ if(JLeapYearQ(year) == TRUE) { /* Here year < 1582 */ printf("%s is a leap year.\n",*argv); return 0; } if( year == 0 ){ printf("There is no year 0.\n"); return 0; } printf("%s is not a leap year.\n",*argv); return 0; } /* Returns TRUE or FALSE according as y is a leap year or not in the Gregorian calendar -- valid on and after 1582. Bear in mind that the Gregorian calendar was not adopted everywhere at the same time. So the folks in Turkey in 1800 might have considered that a leap year, even though this program says they are wrong. I suspect they will not mind :-) */ int GLeapYearQ(int y) { if( (y % 4) != 0 ) return FALSE; if( ( y % 100 ) != 0 ) return TRUE; if( ( y % 400) != 0 ) return FALSE; return TRUE; } /* Returns TRUE or FALSE according as y is a leap year or not in the Julian calendar -- valid before 1582. The Julian Calendar was implemented in the year -45 (45 BC) , which was a leap year. zero. There are no leap years before -45 since the concept was not yet invented. */ int JLeapYearQ(int y) { if( y >= 8 ) return y % 4 == 0 ? TRUE : FALSE; if( y <= -46) return FALSE; if( y > -9 ) return FALSE; return (-y) % 3 == 0 ? TRUE : FALSE; }