ostern.c revision 87235
117849Swosch/* 217849Swosch * Copyright (c) 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin. 317849Swosch * All rights reserved. 413840Swosch * 517849Swosch * Redistribution and use in source and binary forms, with or without 617849Swosch * modification, are permitted provided that the following conditions 717849Swosch * are met: 817849Swosch * 1. Redistributions of source code must retain the above copyright 917849Swosch * notice, this list of conditions and the following disclaimer. 1017849Swosch * 2. Redistributions in binary form must reproduce the above copyright 1117849Swosch * notice, this list of conditions and the following disclaimer in the 1217849Swosch * documentation and/or other materials provided with the distribution. 1317849Swosch * 1417849Swosch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1517849Swosch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1617849Swosch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1717849Swosch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1817849Swosch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1917849Swosch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2017849Swosch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2117849Swosch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2217849Swosch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2317849Swosch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2417849Swosch * SUCH DAMAGE. 2517849Swosch */ 2613840Swosch 2787235Smarkm#include <sys/cdefs.h> 2887235Smarkm 2987235Smarkm__FBSDID("$FreeBSD: head/usr.bin/calendar/ostern.c 87235 2001-12-02 22:44:14Z markm $"); 3087235Smarkm 3115737Sache#include <stdio.h> 3215737Sache#include <stdlib.h> 3313840Swosch#include <string.h> 3415737Sache#include <time.h> 3513840Swosch 3615720Sache#include "calendar.h" 3715720Sache 3813840Swosch/* return year day for Easter */ 3913840Swosch 4070598Sdwmalone/* 4170598Sdwmalone * This code is based on the Calendar FAQ's code for how to calculate 4270598Sdwmalone * easter is. This is the Gregorian calendar version. They refer to 4370598Sdwmalone * the Algorithm of Oudin in the "Explanatory Supplement to the 4470598Sdwmalone * Astronomical Almanac". 4570598Sdwmalone */ 4670598Sdwmalone 4713840Swoschint easter (year) 4813840Swosch int year; /* 0 ... abcd, NOT since 1900 */ 4913840Swosch{ 5070598Sdwmalone int G, /* Golden number - 1 */ 5170598Sdwmalone C, /* Century */ 5270598Sdwmalone H, /* 23 - epact % 30 */ 5370598Sdwmalone I, /* days from 21 March to Paschal full moon */ 5470598Sdwmalone J, /* weekday of full moon */ 5570598Sdwmalone L; /* days from 21 March to Sunday on of before full moon */ 5613840Swosch 5770598Sdwmalone G = year % 19; 5870598Sdwmalone C = year / 100; 5970598Sdwmalone H = (C - C/4 - (8*C+13)/25 + 19*G + 15) % 30; 6070598Sdwmalone I = H - (H/28)*(1 - (H/28)*(29/(H + 1))*((21 - G)/11)); 6170598Sdwmalone J = (year + year/4 + I + 2 - C + C/4) % 7; 6213840Swosch 6370598Sdwmalone L = I - J; 6413840Swosch 6570598Sdwmalone if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) 6670598Sdwmalone return 31 + 29 + 21 + L + 7; 6770598Sdwmalone else 6870598Sdwmalone return 31 + 28 + 21 + L + 7; 6913840Swosch} 7013840Swosch 7113840Swosch/* return year day for Easter or easter depending days 7213840Swosch * Match: Easter([+-][0-9]+)? 7313840Swosch * e.g: Easter-2 is Good Friday (2 days before Easter) 7413840Swosch */ 7513840Swosch 7613840Swoschint 7713840Swoschgeteaster(s, year) 7813840Swosch char *s; 7913840Swosch int year; 8013840Swosch{ 8187235Smarkm int offset = 0; 8215720Sache extern struct fixs neaster; 8313840Swosch 8413840Swosch#define EASTER "easter" 8513840Swosch#define EASTERNAMELEN (sizeof(EASTER) - 1) 8613840Swosch 8715720Sache if (strncasecmp(s, EASTER, EASTERNAMELEN) == 0) 8815720Sache s += EASTERNAMELEN; 8915720Sache else if ( neaster.name != NULL 9015720Sache && strncasecmp(s, neaster.name, neaster.len) == 0 9115720Sache ) 9215720Sache s += neaster.len; 9315720Sache else 9413840Swosch return(0); 9513840Swosch 9613840Swosch#if DEBUG 9713840Swosch printf("%s %d %d\n", s, year, EASTERNAMELEN); 9813840Swosch#endif 9913840Swosch 10013840Swosch /* Easter+1 or Easter-2 10113840Swosch * ^ ^ */ 10213840Swosch 10315720Sache switch(*s) { 10413840Swosch 10513840Swosch case '-': 10613840Swosch case '+': 10715720Sache offset = atoi(s); 10813840Swosch break; 10913840Swosch 11013840Swosch default: 11113840Swosch offset = 0; 11213840Swosch } 11313840Swosch 11413840Swosch return (easter(year) + offset); 11513840Swosch} 116