#!/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;
}