• Welcome to the new COTI server. We've moved the Citizens to a new server. Please let us know in the COTI Website issue forum if you find any problems.
  • We, the systems administration staff, apologize for this unexpected outage of the boards. We have resolved the root cause of the problem and there should be no further disruptions.

Imperial and Sophont Calendrics

robject

SOC-14 10K
Admin Award
Marquis
...are a major pain.

Here's what I've got. Correct me where I'm wrong.

Imperial Day Number (IDN)

IDN = Imperial year x 365 + day

Imperial year = int(IDN / 365)
Imperial day = IDN % 365

With the IDN, one can transform to and from other dates... most of which are annoyingly complicated.
 
Zhodani Date from IDN

This one is a real pain. Corrections coveted.


Code:
#!/usr/bin/env perl
use strict;
use warnings;

my $idn = shift || die "SYNOPSIS: Prints Zhodani date from Imperial Day Number.\nUSAGE: $0 IDN\n";

# These first two are used to transform the Imperial Day Number (IDN) to the Zhodani Day Number (ZDN)
my $ZHODANI_CORRELATION_CONSTANT  = 2459956;  # Imperial day adjustment to help align to the Zhodani day number
my $IMPERIAL_DAYS_PER_ZHODANE_DAY = 1.1258; # or 1.12587

$idn += $ZHODANI_CORRELATION_CONSTANT;
my $zdn = $idn / $IMPERIAL_DAYS_PER_ZHODANE_DAY;

# Now that we have the ZDN, we need to bust it up into olympiads, chten, months and days.  Painful.

my $DAYS_PER_THREE_OLYMPIADS                  = 2200;
my $YEARS_PER_OLYMPIAD                        = 3;
my $DAYS_PER_OLYMPIAD                         = 733;
my $LAST_DAY_OF_FIRST_OLYMPIAD                = 733;
my $FIRST_DAY_OF_LAST_YEAR_OF_FIRST_OLYMPIAD  = 488;
my $LAST_DAY_OF_SECOND_OLYMPIAD               = 1466;
my $FIRST_DAY_OF_LAST_YEAR_OF_SECOND_OLYMPIAD = 1221;
my $FIRST_DAY_OF_THIRD_OLYMPIAD               = 1467;
my $FIRST_DAY_OF_LAST_YEAR_OF_THIRD_OLYMPIAD  = 1710;
my $LAST_DAY_OF_THIRD_OLYMPIAD                = 2199;
my $TYPICAL_DAYS_PER_YEAR                     = 244;

#
#  2200 Zhodani days equals three Olympiads
#  Each olympiad is 733, 733, and 734 days long.
#
my $threeOlympiadCount     = $zdn / $DAYS_PER_THREE_OLYMPIADS;
my $tor                    = $zdn % $DAYS_PER_THREE_OLYMPIADS;

my $olympiadCount          = $YEARS_PER_OLYMPIAD * int($threeOlympiadCount);
my $chten                  = 0;
my $dayIndex               = 0;
my $leapYear               = 0;
my $leapDouble             = 0;
my $holiday                = 0;

#
#  Resolve the olympiad year, day, and leap year indicators
#
if ($tor < $LAST_DAY_OF_FIRST_OLYMPIAD ) # day 0-732
{
   $chten = $tor/$TYPICAL_DAYS_PER_YEAR;      # usually
   $dayIndex = $tor % $TYPICAL_DAYS_PER_YEAR; # usually
   $leapYear = 1 if $tor >= $FIRST_DAY_OF_LAST_YEAR_OF_FIRST_OLYMPIAD;
}
elsif ($tor < $LAST_DAY_OF_SECOND_OLYMPIAD ) # day 733-1466
{
   $olympiadCount += 1;
   $chten = ($tor-$DAYS_PER_OLYMPIAD)/$TYPICAL_DAYS_PER_YEAR; # usually
   $dayIndex = $tor % $TYPICAL_DAYS_PER_YEAR;  # usually
   $leapYear = 1 if $tor >= $FIRST_DAY_OF_LAST_YEAR_OF_SECOND_OLYMPIAD;
}
else # day 1467-
{
   $olympiadCount += 2;
   $chten = ($tor-$FIRST_DAY_OF_THIRD_OLYMPIAD)/$TYPICAL_DAYS_PER_YEAR; # usually
   $dayIndex = $tor % $TYPICAL_DAYS_PER_YEAR;   # usually
   $leapYear = 1 if $tor >= $FIRST_DAY_OF_LAST_YEAR_OF_THIRD_OLYMPIAD;
   $leapDouble = $leapYear;
}


$chten++;
$dayIndex++;

=pod
    // Day offsets into the year are as follows:
    /*
    Offset  Season/Holiday    notes
    1       Dranshrin        [holiday]
    1       Atrint           (days 2-41)
    42      Viepchaklstial   [holiday]
    42      Vrienstial       (days 43-82)
    83      Dranzhrinatch    [holiday]
    83      Atchafser        (days 84-123)
    124     Ataniebl         (days 124-163)
    164     Kazdievlstial    [holiday]
    164     Atshiavl         (days 165-204)
    [205     Thequzastial, i.e. Leap Day]
    205     Atpaipr [206 on a Leap Year] (days 205-244)
    or (days 206-245)
    */
=cut

my @seasons = qw/Dranshrin Atrint Viepchakl Vrien Dranzhrin Atchafset Ataniebl Kazdievl Atshiavl Thequze Atpaipr Atrithequza/;

my $season;
my $dayOffset = 0;

my $DRANSHRIN = 1;
my $ATRINT    = 41;
my $VIEPCHAKL = 42;
my $VRIEN     = 82;
my $DRANZHRIN = 83;
my $ATCHAFSET = 123;
my $ATANIEBL  = 163;
my $KAZDIEVL  = 164;
my $ATSHIAVL  = 204;
my $THEQUZE   = 205;
my $ATPAIPR   = 205;

if    ( $dayIndex == $DRANSHRIN ) { $season = $seasons[0]; $holiday = 1; }
elsif ( $dayIndex <= $ATRINT    ) { $season = $seasons[1]; $dayOffset = 1; }
elsif ( $dayIndex == $VIEPCHAKL ) { $season = $seasons[2]; $holiday = 1; }
elsif ( $dayIndex <= $VRIEN     ) { $season = $seasons[3]; $dayOffset = 42; }
elsif ( $dayIndex == $DRANZHRIN ) { $season = $seasons[4]; $holiday = 1; }
elsif ( $dayIndex <= $ATCHAFSET ) { $season = $seasons[5]; $dayOffset = $DRANZHRIN; }
elsif ( $dayIndex <= $ATANIEBL  ) { $season = $seasons[6]; $dayOffset = $ATCHAFSET+1; }
elsif ( $dayIndex == $KAZDIEVL  ) { $season = $seasons[7]; $holiday = 1; }
elsif ( $dayIndex <= $ATSHIAVL  ) { $season = $seasons[8]; $dayOffset = $KAZDIEVL; }
elsif ( $dayIndex == $THEQUZE && $leapYear ) { $season = $seasons[9]; $holiday = 1; }
elsif ( $leapDouble ) { $season = $seasons[11]; $holiday = 1; }
else
    {
        $season = $seasons[10];
        $dayOffset = $ATPAIPR;
    }

my $monthDay = ($dayIndex - $dayOffset);

if ( $holiday )
{
   printf "%d.%d %s", $olympiadCount, $chten, $season;
}
else
{
   printf "%d.%d %s %d", $olympiadCount, $chten, $season, $monthDay;
}
 
Last edited:
Programatic is the way to work it. Makes my head hurt just thinking about that math.
 
Would be more useful if all the magic numbers were defined.

VERY good point. OP UPDATED!

(Until last night, I wasn't sure what all the magic numbers' VALUES were, much less which ones were going to be used).
 
Last edited:
Back
Top