1100882Smike/*- 2100882Smike * Copyright (c) 1997 Wolfgang Helbig 3100882Smike * All rights reserved. 4100882Smike * 5100882Smike * Redistribution and use in source and binary forms, with or without 6100882Smike * modification, are permitted provided that the following conditions 7100882Smike * are met: 8100882Smike * 1. Redistributions of source code must retain the above copyright 9100882Smike * notice, this list of conditions and the following disclaimer. 10100882Smike * 2. Redistributions in binary form must reproduce the above copyright 11100882Smike * notice, this list of conditions and the following disclaimer in the 12100882Smike * documentation and/or other materials provided with the distribution. 13100882Smike * 14100882Smike * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15100882Smike * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16100882Smike * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17100882Smike * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18100882Smike * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19100882Smike * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20100882Smike * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21100882Smike * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22100882Smike * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23100882Smike * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24100882Smike * SUCH DAMAGE. 25100882Smike */ 26100882Smike 27100882Smike#include <sys/cdefs.h> 28100882Smike__FBSDID("$FreeBSD$"); 29100882Smike 30100882Smike#include "calendar.h" 31100882Smike 32100882Smiketypedef struct date date; 33100882Smike 34100882Smikestatic int easterodn(int y); 35100882Smike 36100882Smike/* Compute Easter Sunday in Gregorian Calendar */ 37100882Smikedate * 38100882Smikeeasterg(int y, date *dt) 39100882Smike{ 40100882Smike int c, i, j, k, l, n; 41100882Smike 42100882Smike n = y % 19; 43100882Smike c = y / 100; 44100882Smike k = (c - 17) / 25; 45100882Smike i = (c - c/4 -(c-k)/3 + 19 * n + 15) % 30; 46100882Smike i = i -(i/28) * (1 - (i/28) * (29/(i + 1)) * ((21 - n)/11)); 47100882Smike j = (y + y/4 + i + 2 - c + c/4) % 7; 48217147Stijl l = i - j; 49217147Stijl dt->m = 3 + (l + 40) / 44; 50100882Smike dt->d = l + 28 - 31*(dt->m / 4); 51100882Smike dt->y = y; 52100882Smike return (dt); 53100882Smike} 54100882Smike 55100882Smike/* Compute the Gregorian date of Easter Sunday in Julian Calendar */ 56100882Smikedate * 57100882Smikeeasterog(int y, date *dt) 58100882Smike{ 59100882Smike 60100882Smike return (gdate(easterodn(y), dt)); 61100882Smike} 62100882Smike 63100882Smike/* Compute the Julian date of Easter Sunday in Julian Calendar */ 64100882Smikedate * 65100882Smikeeasteroj(int y, date * dt) 66100882Smike{ 67100882Smike 68100882Smike return (jdate(easterodn(y), dt)); 69100882Smike} 70100882Smike 71100882Smike/* Compute the day number of Easter Sunday in Julian Calendar */ 72100882Smikestatic int 73100882Smikeeasterodn(int y) 74100882Smike{ 75100882Smike /* 76100882Smike * Table for the easter limits in one metonic (19-year) cycle. 21 77100882Smike * to 31 is in March, 1 through 18 in April. Easter is the first 78100882Smike * sunday after the easter limit. 79100882Smike */ 80100882Smike int mc[] = {5, 25, 13, 2, 22, 10, 30, 18, 7, 27, 15, 4, 81100882Smike 24, 12, 1, 21, 9, 29, 17}; 82100882Smike 83100882Smike /* Offset from a weekday to next sunday */ 84100882Smike int ns[] = {6, 5, 4, 3, 2, 1, 7}; 85100882Smike date dt; 86100882Smike int dn; 87100882Smike 88100882Smike /* Assign the easter limit of y to dt */ 89100882Smike dt.d = mc[y % 19]; 90100882Smike 91100882Smike if (dt.d < 21) 92100882Smike dt.m = 4; 93100882Smike else 94100882Smike dt.m = 3; 95100882Smike 96100882Smike dt.y = y; 97100882Smike 98100882Smike /* Return the next sunday after the easter limit */ 99100882Smike dn = ndaysj(&dt); 100100882Smike return (dn + ns[weekday(dn)]); 101100882Smike} 102100882Smike