Theiling Online    Sitemap    Conlang Mailing List HQ   

Re: Programming a calendar system

From:Mark J. Reed <markjreed@...>
Date:Friday, April 30, 2004, 1:00
Okay, now for the nitty gritty.

Problem: Given the Aréqan calendar system as laid out in Carsten's
email, with the correspondence that 1-1-1 00:00:00 Aréqan = -986-08-26
22:18:00 UTC Gregorian (which is the same date as September 4, 987 BC
Julian), calculate the current Aréqan date and time given the UNIX
time_t value.

The first part of this is all prep; it only has to be done once, and
doesn't go into the code; it's just math.

The first thing we have to do is find out what UNIX time_t 0 is in
Aréqan.  That's 1970-01-01 00:00:00 UTC.  Fortunately, I have a
handy-dandy Julian Day calculator handy.

-986-08-26 22:18:00 UTC Gregorian is JD 1,361,168.42917
1970-01-01 00:00:00 UTC Gregorian is JD 2,440,587.50000

Subtract: 2,440,587.5 - 1,361,168.42917 = 1,079,419.07083 Earth days
from the start of the Aréqan epoch to the start of the UNIX epoch.
There are 24 x 60 x 60 = 86,400 seconds in each day, so that's
1,079,419.07083 x 86,400 = 93,261,807,720 Earth seconds.

The next step is to convert that into Aréqan units.  Your email said
that 1 Aréqan second is 1.2 Earth seconds, so we divide 93,261,807,720
by 1.2 yielding exactly 77,718,173,100 Aréqan seconds.

Now we find out what that is in terms of larger units.

77,718,173,100 sec x 1 min/72 sec = 1,079,419,070 min 60 sec
 1,079,419,070 min x 1  hr/18 min =    59,967,726  hr  2 min
    59,967,726 hr  x 1 day/27 hr  =     2,221,026 days 24 hr

The next step up could be weeks, but that won't tell us what the date is
since weeks don't figure into the date.  We can't do months because the
length of months varies.  So that means years come next.  But we want
calendar years, not solar years; the calendar is designed to keep them
in synch, but not perfectly; there could be a day or so difference.  And
calendar years are not a constant size.  So we have to find a cycle that
is of constant size, and in this case it's easy - four years are 1,823
days.  On Earth we call that a tetrad (or Olympiad), and as long as
we're repurposing Earth unit names, we might as well use that one too.

     2,221,026 days x 1 tetrad/1823 days = 1,218 tetrads 612 days

        1,218 tetrads x 4 years/1 tetrad = 4872 years
All  but the last year of a tetrad are 456 days, so:

        612 days x 1 year/456 days = 1 year 156 days

So in Aréqan units, the start of the UNIX epoch occurs 4873 years, 156
days, 24 hours, 2 minutes, and 60 seconds into the Aréqan epoch.

What does that mean?  Well, first of all, we're dealing with intervals
and we want to turn it into a count.  That always involves an offset of
1 - that is, 0 years into the epoch is already year 1, 0 months into the
year is already month 1, 0 days into the month is already day 1, etc.
At the end of a complete year into the epoch, it's the first day of
the first month.  So after 1 year, it's 2-1-1; after 10 years, it's
11-1-1, etc.  So after 4873 years, it's 4874-1-1.  Then add 156 more
days to that and you get 4874-1-157.  Except, of course, that the first
month doesn't have 157 days in it.  They way to fix that is to keep
subtracting the size of the month and incrementing the month number
until you get something that fits.

The first month has 25 days;  157 - 25 = 132    4874-02-132
The second month has 25 days; 132 - 25 = 107    4874-03-107
The third month has 25 days;  107 - 25 =  82    4874-04-82
The fourth month has 25 days;  82 - 25 =  57    4874-05-57
The fifth month has 25 days;   57 - 25 =  32    4874-06-32
The sixth month has 25 days;   32 - 25 =   6    4874-07-06

So the UNIX epoch occurred at 4874-07-06 at 24:02:60 Aréqan time.

The math is unworkable if you start in the middle of a cycle, however.
So what we really want is the UNIX time_t value of the start of the next
tetrad, which is 4877-01-01 00:00:00.  Let's bump up each of our Aréqan
units in turn until we get there, keeping track of how much time we add,
then convert that back to Earth seconds to get the corresponding time_t
value.


First, increment the seconds                0           4874-07-06 24:02:60
to the next minute; to get
from 60 to 72 is 12 seconds      +12    =  12       =  4874-07-06 24:03:00

Then increment the minutes to
get to the next hour.  To
get from 3 to 18 you add
15 minutes, which is 15x72=
1080 seconds, plus the 12 we
just added is a total of 1092. +15:00 = 1092       =  4874-07-06 25:00:00

Then increment the hours to
get to the next day.  To get
from 25 to 27 you add 2 hours,
which is 2 x 18 = 36 minutes,
which is 36 x 72  = 2592 sec,
plus 1092 = 3684.              +2:00:00 = 3684       = 4874-07-07 00:00:00

Now increment the days to get
to the next month.  The 7th
month has 24 days, which means
to get to the first of the 8th
month we have to add 25 - 7 =
18.  18 days is  18 x 27 = 486
hours = 486 x 18 = 8,748 minutes
= 8,748 * 72 = 629,856 seconds,
plus 3684 = 629,856 sec.        + 18 days = 629,856 =   4874-08-01 00:00:00

Now add months to get to the
next year.  The 8th month
has 26 days; the 9th has 30
(since 4874 isn't a leap year);
the 10th and 11th have 26 each;
the 12th has 24; and the 13th through
18th have 25 days each.
26 + 30 + 2 x 26 + 24 + 6 x 25 =
56 + 52 + 24 + 150 =
108 + 174 = 282 days.
That's 282 x 27 =
7,614 hours =
7,614 x 18 =
137,052 min =
137,052 x 72 =
9,867,744 sec
+ 629,856 sec =
10497600 sec            + 282 days      =  10,497,600   = 4875-01-01

Add days to
get to the next
year; 4875 is not
leap, so it
has  456 days =
15956352 sec +
10497600 =
26453952 sec            + 456 days      =  26,453,952   = 4876-01-01

4876 is a leap
year, so it onlyh
has 455 days =
15,921,360 sec +
26,453,952 =
42,375,312 sec          + 455 days      = 42,375,312 sec  = 4877-01-01

That's our desired point - the start of a tetrad, 42,375,312 Aréqan
seconds after UNIX time 0.   Since each of those Aréqan seconds
is 1.2 SI seconds, thats time_t = 42,375,312 x 1.2 = 50,850,374.4
(which happens to be Thursday, August 12, 1971, at 13:06:14 UTC).

Now we can implement.  Code to follow.