Here's the main bit of code; the two documents from which I derived it
are over the 40k limit. One is the calendar FAQ text version. The other
is a file easter_date.txt that is a thread from:

Newsgroups: soc.religion.christian
From: [EMAIL PROTECTED] (Mike Siemon)
Subject: Easter algorithms I
Organization: AT&T Bell Laboratories
Approved: [EMAIL PROTECTED]

Does anyone want such files?

Anyway, the implemented formulas are below. The header files are just
for keeping track of Palm-specific variables for different modules.

/*****************************************************************************
 *
 * Created with Falch.net DeveloperStudio
 * http://www.falch.net/
 * 
 * Created : 4/11/01 12:18:42 AM
 * Creator : (Unknown)
 *

****************************************************************************/
#include <Pilot.h>
#include "Easter.h"
#include "Easter_res.h"   

extern Boolean England;
extern UInt16 YearAD;
Char Orthodox_Julian[20], Orthodox_Gregorian[20], Western[20];

typedef enum {Julian,Gregorian} calendar;

/*      The "Golden Number" is the order of the year in the 19-year lunar
cycle.
 *      It is the same in Julian or Gregorian calendars, and is listed in the
 *      output of this program under the heading GN.
 */

int     GoldenNumber(int year)
{
        return ((year % 19) + 1);
}

/*      All dates in this program are referred to March 1st; so 32 means
 *      April 1 and 0 means February 28th or 29th.  Leap years are needed
 *      for printing February dates (and for dominical letters).
 */

int     Leap(int year, calendar style)
{
        if (year % 4)
                return 0;
        else switch(style) {
                case Julian:    return 1;
                case Gregorian: return (year % 100 || year % 400 == 0);
        }
}

#define century (year/100)

/*      Gregorian solar correction -- this is the number of days difference
 *      between Julian and Gregorian civil dates, in effect the number of
 *      excess leap years in the Julian calendar since the time of Nicea.
 *      This correction derives from the Gregorian introduction of non-leap
 *      century years, giving mean tropical year = 365.2425 days.
 */

int     Solar(int year)
{
        return (century - century/4 - 2);
}

/*      Gregorian lunar correction -- this is only used for the computation
of
 *      the paschal new moon (via epact), but might as well be pulled out on
 *      its own.  I give the pedantically correct version.
 *      This correction derives from the mean lunar month being 29.53059 days
 *      instead of the 6939.75/235 assumed in the Julian calendar.  It is one
 *      days in (roughly) 312.5 years, or 8 days in 2500 years.
 */

int     Lunar(int year)
{
        return ((century - 15 - (century-17)/25)/3);
}

/*      Epact is the "age" of the moon on March 1st (same as January 1st);
 *      It (may have) derived from Greek methods of calculating the extra
 *      ("epagomenal") months intercalated into the regular 12 at 7 points
 *      of the 19-year Metonic cycle.  However, it is not used in Julian
 *      easter calculations and is provided here only for Gregorian NewMoon.
 */

int     Epact(int year)
{
        int     epact;

        epact = (11*GoldenNumber(year) - Solar(year) + Lunar(year)) % 30;
        if (epact < 0)
                epact += 30;
        return epact;
}

/*      Here's the hard one.  Keep in mind that there are several artificial
 *      conventions -- the equinox is ALWAYS March 21; new moon is ALWAYS the
 *      date on which a fictitious "average" moon is one day old, and the
full
 *      moon is 13 days later, on the 14th of the month.  In the Julian
version
 *      (and MOSTLY in the Gregorian) the pre-paschal month has 30 days.  All
 *      of this works out keeping fairly close to astronomical reality in the
 *      Gregorian case, but it is not necessarily exact.
 */

int     NewMoon(int year, calendar style)
{
        int     new_moon, epact;

        switch (style) {
                case Julian:
                        new_moon = (4 - 11*GoldenNumber(year)) % 30;
                        while (new_moon < 8)
                                new_moon += 30;
                        return new_moon;
                case Gregorian:
                        epact = Epact(year);
                        new_moon = 31-epact;
                        if (new_moon < 8) {
                                new_moon += 30;
                                if (epact == 24 || epact == 25 && year%19 > 10)
                                        new_moon--;
                        }
                        return new_moon;
        }
}

int     WeekDay(int date, int year, calendar style)
{
        int     d;

        d = date + year + year/4;
        if (style == Gregorian)
                d -= Solar(year);
        return  (d % 7);
}

/*      Given the Paschal full moon, we just step to the next Sunday ...
 */

int     Easter(int year, calendar style)
{
        int     paschal_moon;

        paschal_moon = NewMoon(year, style) + 13;
        return (paschal_moon + 7 - WeekDay(paschal_moon, year, style));
}


/* The rest of the code turns numbers into human-readable output */

static Boolean frmDates_fldOrthodoxJulian_OnSelect(EventPtr event)
{
        // Insert code for fldOrthodoxJulian
        FormPtr form;
        FieldPtr field;

        form = FrmGetActiveForm();
        field =
FrmGetObjectPtr(form,FrmGetObjectIndex(form,fldOrthodoxJulian));
        FldCopy(field); 
        return true;
}

static Boolean frmDates_fldOrthodoxGregorian_OnSelect(EventPtr event)
{
        // Insert code for fldOrthodoxGregorian
        FormPtr form;
        FieldPtr field;

        form = FrmGetActiveForm();
        field =
FrmGetObjectPtr(form,FrmGetObjectIndex(form,fldOrthodoxGregorian));
        FldCopy(field); 
        return true;
}

static Boolean frmDates_fldWesternGregorian_OnSelect(EventPtr event)
{
        // Insert code for fldWesternGregorian
        FormPtr form;
        FieldPtr field;

        form = FrmGetActiveForm();
        field =
FrmGetObjectPtr(form,FrmGetObjectIndex(form,fldWesternGregorian));
        FldCopy(field); 
        return true;
}

static Boolean frmDates_cmdNewYear_OnSelect(EventPtr event)
{
        // Insert code for cmdNewYear
        FrmGotoForm(frmMain);
        return true;
}

Boolean frmDates_HandleEvent(EventPtr event)
{
        FormPtr form;
        FieldPtr J1, J2, G;
        Boolean handled = false;
        int year, easterJ1, easterJ2, easterG;

        switch (event->eType)
        {
                case ctlSelectEvent:
                        switch (event->data.ctlSelect.controlID)
                        {
                                // fldOrthodoxJulian receives an event
                                case fldOrthodoxJulian:
                                        handled = 
frmDates_fldOrthodoxJulian_OnSelect(event);
                                        break;
                                // fldOrthodoxGregorian receives an event
                                case fldOrthodoxGregorian:
                                        handled = 
frmDates_fldOrthodoxGregorian_OnSelect(event);
                                        break;
                                // fldWesternGregorian receives an event
                                case fldWesternGregorian:
                                        handled = 
frmDates_fldWesternGregorian_OnSelect(event);
                                        break;
                                // cmdNewYear receives an event
                                case cmdNewYear:
                                        handled = 
frmDates_cmdNewYear_OnSelect(event);
                                        break;
                        }
                        break;
                case frmOpenEvent:
                        form = FrmGetActiveForm();
                        J1 = 
FrmGetObjectPtr(form,FrmGetObjectIndex(form,fldOrthodoxJulian));
                        J2 =
FrmGetObjectPtr(form,FrmGetObjectIndex(form,fldOrthodoxGregorian));
                        G  =
FrmGetObjectPtr(form,FrmGetObjectIndex(form,fldWesternGregorian));
                        
                        // Calculate the necessary dates
                        year = (int) YearAD;
                        easterJ1 = Easter(year, Julian);
                        easterJ2 = easterJ1 + Solar(year);
                        easterG  = Easter(year, Gregorian);

                        if (easterJ1 > 31)
                                StrPrintF(Orthodox_Julian, "%2d April AD %d", 
easterJ1-31, year);
                        else
                                StrPrintF(Orthodox_Julian, "%2d March AD %d", 
easterJ1, year);

                        if (easterJ2 > 92)
                                StrPrintF(Orthodox_Gregorian, "%2d June AD %d", 
easterJ2-92, year);
                        else if (easterJ2 > 61)
                                StrPrintF(Orthodox_Gregorian, "%2d May AD %d", 
easterJ2-61, year);
                        else if (easterJ2 > 31)
                                StrPrintF(Orthodox_Gregorian, "%2d April AD 
%d", easterJ2-31, year);
                        else
                                StrPrintF(Orthodox_Gregorian, "%2d March AD 
%d", easterJ2, year);

                        if (easterG > 31)
                                StrPrintF(Western, "%2d April AD %d", 
easterG-31, year);
                        else
                                StrPrintF(Western, "%2d March AD %d", easterG, 
year);

                        if (year < 1583)
                        {
                                FldSetTextPtr(J1,Orthodox_Julian);
                                FldSetTextPtr(J2,"");
                                FldSetTextPtr(G,"");
                        }
                        else if (year < 1753 && England)
                        {
                                FldSetTextPtr(J1,Orthodox_Julian);
                                FldSetTextPtr(J2,Orthodox_Gregorian);
                                FldSetTextPtr(G,"");
                        }
                        else
                        {
                                FldSetTextPtr(J1,Orthodox_Julian);
                                FldSetTextPtr(J2,Orthodox_Gregorian);
                                FldSetTextPtr(G,Western);
                        }

                        // Repaint form on open
                        FrmDrawForm(form);
                        handled = true;
                        break;
        }

        return handled;
}

On Sun, 2008-06-22 at 19:38 +0200, Hans Hagen wrote:
> Charles P. Schaum wrote:
> > Some calendar links, FYI:
> > 
> > http://astro.nmsu.edu/~lhuber/leaphist.html
> > http://www.smart.net/~mmontes/ec-cal.html
> > http://www.tondering.dk/claus/calendar.html
> > http://tycho.usno.navy.mil/vphase.html
> > 
> > I would be happy to make available the C code for an Easter date
> > calculator that I implemented on the Palm III. I used the complex
> > algorithm that figures the "age" of the moon at New Year's. It
> > originally came from Bell Labs, I think.
> 
> well, we can make a nice l-calendar.lua module together
> 
> just provide me the calculations (i can implement to lua code but i have 
> no time to figure out all the logic)
> 
> 
> Hans
> 
> -----------------------------------------------------------------
>                                            Hans Hagen | PRAGMA ADE
>                Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
>       tel: 038 477 53 69 | fax: 038 477 53 74 | www.pragma-ade.com
>                                               | www.pragma-pod.nl
> -----------------------------------------------------------------
> ___________________________________________________________________________________
> If your question is of interest to others as well, please add an entry to the 
> Wiki!
> 
> maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
> webpage  : http://www.pragma-ade.nl / http://tex.aanhet.net
> archive  : https://foundry.supelec.fr/projects/contextrev/
> wiki     : http://contextgarden.net
> ___________________________________________________________________________________

___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the 
Wiki!

maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context
webpage  : http://www.pragma-ade.nl / http://tex.aanhet.net
archive  : https://foundry.supelec.fr/projects/contextrev/
wiki     : http://contextgarden.net
___________________________________________________________________________________

Reply via email to