ostern.c revision 87235
141502Swpaul/* 241502Swpaul * Copyright (c) 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin. 341502Swpaul * All rights reserved. 441502Swpaul * 541502Swpaul * Redistribution and use in source and binary forms, with or without 641502Swpaul * modification, are permitted provided that the following conditions 741502Swpaul * are met: 841502Swpaul * 1. Redistributions of source code must retain the above copyright 941502Swpaul * notice, this list of conditions and the following disclaimer. 1041502Swpaul * 2. Redistributions in binary form must reproduce the above copyright 1141502Swpaul * notice, this list of conditions and the following disclaimer in the 1241502Swpaul * documentation and/or other materials provided with the distribution. 1341502Swpaul * 1441502Swpaul * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1541502Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1641502Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1741502Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1841502Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1941502Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2041502Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2141502Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2241502Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2341502Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2441502Swpaul * SUCH DAMAGE. 2541502Swpaul */ 2641502Swpaul 2741502Swpaul#include <sys/cdefs.h> 2841502Swpaul 2941502Swpaul__FBSDID("$FreeBSD: head/usr.bin/calendar/ostern.c 87235 2001-12-02 22:44:14Z markm $"); 3041502Swpaul 3141502Swpaul#include <stdio.h> 3241502Swpaul#include <stdlib.h> 33122678Sobrien#include <string.h> 34122678Sobrien#include <time.h> 35122678Sobrien 3641502Swpaul#include "calendar.h" 3741502Swpaul 3841502Swpaul/* return year day for Easter */ 3941502Swpaul 4041502Swpaul/* 4141502Swpaul * This code is based on the Calendar FAQ's code for how to calculate 4241502Swpaul * easter is. This is the Gregorian calendar version. They refer to 4341502Swpaul * the Algorithm of Oudin in the "Explanatory Supplement to the 4441502Swpaul * Astronomical Almanac". 4541502Swpaul */ 4641502Swpaul 47131503Sbmsint easter (year) 4841502Swpaul int year; /* 0 ... abcd, NOT since 1900 */ 4941502Swpaul{ 5041502Swpaul int G, /* Golden number - 1 */ 5141502Swpaul C, /* Century */ 5241502Swpaul H, /* 23 - epact % 30 */ 5341502Swpaul I, /* days from 21 March to Paschal full moon */ 5441502Swpaul J, /* weekday of full moon */ 5541502Swpaul L; /* days from 21 March to Sunday on of before full moon */ 5641502Swpaul 5741502Swpaul G = year % 19; 5841502Swpaul C = year / 100; 5941502Swpaul H = (C - C/4 - (8*C+13)/25 + 19*G + 15) % 30; 6041502Swpaul I = H - (H/28)*(1 - (H/28)*(29/(H + 1))*((21 - G)/11)); 6141502Swpaul J = (year + year/4 + I + 2 - C + C/4) % 7; 6241502Swpaul 6341502Swpaul L = I - J; 6441502Swpaul 6541502Swpaul if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) 6641502Swpaul return 31 + 29 + 21 + L + 7; 6741502Swpaul else 6841502Swpaul return 31 + 28 + 21 + L + 7; 69129878Sphk} 7041502Swpaul 7141502Swpaul/* return year day for Easter or easter depending days 7241502Swpaul * Match: Easter([+-][0-9]+)? 7341502Swpaul * e.g: Easter-2 is Good Friday (2 days before Easter) 7441502Swpaul */ 7541502Swpaul 7641502Swpaulint 7741502Swpaulgeteaster(s, year) 7841502Swpaul char *s; 7941502Swpaul int year; 80131503Sbms{ 81131503Sbms int offset = 0; 8241502Swpaul extern struct fixs neaster; 8341502Swpaul 8441502Swpaul#define EASTER "easter" 8549610Swpaul#define EASTERNAMELEN (sizeof(EASTER) - 1) 8649610Swpaul 8749610Swpaul if (strncasecmp(s, EASTER, EASTERNAMELEN) == 0) 8841502Swpaul s += EASTERNAMELEN; 8951432Swpaul else if ( neaster.name != NULL 9051432Swpaul && strncasecmp(s, neaster.name, neaster.len) == 0 9151432Swpaul ) 92119288Simp s += neaster.len; 93119288Simp else 9441502Swpaul return(0); 9541502Swpaul 9641502Swpaul#if DEBUG 9741502Swpaul printf("%s %d %d\n", s, year, EASTERNAMELEN); 9841502Swpaul#endif 99113506Smdodd 100113506Smdodd /* Easter+1 or Easter-2 10159758Speter * ^ ^ */ 10259758Speter 10351432Swpaul switch(*s) { 10451432Swpaul 10551432Swpaul case '-': 106110168Ssilby case '+': 107110168Ssilby offset = atoi(s); 10841502Swpaul break; 10941502Swpaul 11041502Swpaul default: 11141502Swpaul offset = 0; 11241502Swpaul } 11341502Swpaul 11441502Swpaul return (easter(year) + offset); 11541502Swpaul} 11662653Swpaul