Functions that, given a calendar date (Gregorian orJulian), calculate a day number (the Julian day number), and vice-versa.Just for fun, given a year number, calculate Easter Sunday's date. These routines are the only sensible way to calculate the day of theweek, the number of days between two dates, or the date some number of days after a given date, etc.

{--------------------------------Turgid date
messing--------------------------}
const EdictOfGregory = 2299161;{A special day in the history of
calendars.}
Procedure ElevenDayRiot(JD: longint);
Begin
if JD >= EdictOfGregory then exit;
writeln('NB! Prior to y1582m10d15 the Gregorian calendar did not
exist
anywhere!');
writeln('Nobody used this date to refer to this day.');
End;
const JulianWeekday: array[0..6] of string[9] = {Properly, Sunday is
the
first day of the week.}
('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday');
Function JDay(fY,fM,fD:number): number; {Julian Day Number from the
Gregorian calendar date.}
{ The Julian Day Count is *not* the Julian Calendar introduced by
Julius
Caesar.
It is named for Julius Scaliger (a historian), the father of Josephus
Justus Scaliger,
who published the concept in 1583.
The Julian Day Number is a continuous run of days counted since the
nominal
first of January 4713BC on the *Julian Calendar* for that date, and
called
"proleptic" because the Julian calendar didn't exist then.
In 1583, there were no known historical events before 4713 BC. It
was
in 1650
that James Ussher, Anglican Archbishop of Armargh and Primate of
Ireland,
after
an analysis of Biblical genealogies and historical connections,
declared
that the
world was created on Sunday the 23'rd day of October 4004BC, except
that
the BC
scheme wasn't in use then. He gave the year as 710 of the first Julian
era,
or 709 years after its nominal start. Not 710: the count starts with
one.
His article, Annales Veteris et Novi Testamenti, is quite clear and
yet
has
been thoroughly misunderstood, misquoted and confused with the works of
others and
of other dates such as the date and time of Adam's creation. Then there
followed
adjustments and corrections. There are of course dates from different
traditions,
with their own misinterpretations and so on.
The starting point for the Julian calendar was chosen to be the year
when three
cycles would have coincided:
The solar cycle: There are seven days of the week that a year can
start
with, but thanks to leap years, the cycle length is 4*7 = 28 and in
the
Julian
calendar, there is only the divisibility by four rule for leap
years.
The Metonic or "golden number" cycle: The lunar phases and days
of
the year
(almost) repeat in a 19-year cycle, as stated by Meton of Athens in
432BC,
but well-known to the Babylonians and others: 235 lunations to 19
years.
The indiction cycle: a Roman tax cycle of 15 years declared by
Constantine
the Great on the 1'st September 312 AD. Dates were often recorded
using
this,
hence the interest by historians.
And so 28*19*15 = 7980.
In the last year of the solar cycle, January 1 is a Sunday, the
first
day of the
week. In the first year of the Metonic cycle, the New Moon falls on
January 1.
The first indiction cycle began on 1 September 327, not that all users
kept to this.
In about AD 523 the scholar Dionysius Exiguus (Dennis the Short) was
asked
by Pope Boniface to devise a scheme to calculate the dates of Easter
that
followed the rules decided on by the council of Nicea. For centuries,
years had
been numbered from the reign of emperor Diocletian but rather than
honour
a persecutor of Christians, Dionysius chose to number the years since
the
birth of Christ and fixed Jesus' birth so as to fall on 25'th December
753
AUC
(Ab Urbe Condita, the traditional date for the founding of Rome by
Romulus
in
753BC), making the current era start with AD 1 on 1 January 754 AUC,
there
being
no year zero, neither between BC and AD, nor for the count of AUC. In
Julian terms,
the year of Christ's birth was the 9th year of the solar cycle, the
first
year of
the Metonic cycle, and the third year of the Indiction cycle, which
wasn't
used then.
This dating has been disputed from the start, since the Gospel of
Matthew tells
us that Jesus was born under the reign of King Herod the Great, who
died
in 4 BC.
Taking the year when each cycle was in its first year as the first
year
of
the Julian period, then the year of Christ's birth would be year 4713,
making the
first year 4713 BC in the Julian calendar, were it to have existed
then.
In 1849, the astronomer John F. Herschel turned Scaliger's calendar
into the
astronomical Julian Date system, taking January 1, 4713 BC as JD = 0,
and
counting
day numbers from that date.
This routine computes the JDay on the basis of the *Gregorian*
calendar,
which was imposed by edict of Pope Gregory XIII on Friday 15'th October
1582,
and disregarded by Protestants and others.
The English converted in 1752, occasioning the Eleven-Day riots,
eleven
days,
because by the time of conversion, the English had regarded 1700 as a
leap
year,
which it isn't in the Gregorian calendar. The riots were caused by
creditors
wanting a full month's payment, not because the peasants were thick.
Bankers
likewise refused to pay tax on March 25'th (the traditional date) which
had
become eleven days early. As ever, the City of London bankers had
clout,
and
they paid on April 5'th, which still remains the end of the fiscal
year.
This meant that for the Catholics, Thursday 4'th October 1582 (the
date's
name in the Julian calendar) was followed by Friday 15'th October 1582,
the
Gregorian name for the next day. For the English (but not the Scots)
the
jump
was Wednesday 2'nd September to Thursday 14'th September 1752.
Thus, Isaac Newton was not born in the same year that Glaileo
Galilei
died,
8'th January 1642 Gregorian or 29'th December 1641 Julian. Newton's
birthday
has the name 25'th December 1642 in the Julian calendar, but 4'th
January
1643
in the Gregorian. A gap of 361 days.
Because Julian Day Numbers are used by astronomers, they found it
convenient
to have the day number change at noon, when they weren't making
observations
(in Europe) so 1582/10/15 started on JDay 2299160.5 (just past
midnight,
GMT,
not that GMT was a notion in use at the time), approached noon GMT at
2299160.999,
continued into afternoon at Jday 2299161.001 and at midnight attained
JDay
2299161.5. So, instead of a day number, perhaps it would better be
termed
a
Julian Night Number...
This routine computes as if for noon+ on the nominated date, that
is,
JDay(1582,10,15) = 2299161. It is easy to be out by one. Note that the
fD
parameter is not truncated. Thus, you can take the hour, minute, and
second time
to generate a fraction of a day, between 0 and one, as a part of the
day
value.
Making sense of time zones and daylight saving is up to you. I'd
suggest
making the adjustment to the final value, not to the parameters,
however
the
day parameter can have any value, even negative.
This is the infamous routine of H. F. Fliegel and T.C. van Flandern,
from Communications of the ACM, Vol. 11, No. 10, October, 1968.
Though I see no reason why they used I,J,K instead of Y,M,D as
names.
Carefully typed in by R.N.McLean (whom God preserve) December
XXMMIIX.
Example: Y = 1970, M = 1, D = 1; JDay = 2440588, a Thursday.}
var Y,M: longint; {Beware the 1461*etc.}
Begin
Y:=Trunc(fY); M:=Trunc(fM); {These shouldn't have fractional parts
anyway.}
if Y < 1 then Y:=Y + 1; {Thus there is no year zero between 1BC and
1AD.}
JDay:=1461*(Y + 4800 + (M - 14) div 12) div 4
+ 367*(M - 2 - (M - 14) div 12 *12) div 12
- 3*((Y + 4900 + (M - 14) div 12) div 100) div 4
+ fD - 32075;
End;
Function Greg(fj: number): number; {Gregorian calendar date from
Julian
Day Number.}
{ The inverse procedure is even worse.
This converts 2299161 back to 1582/10/15 and the Round will cause
229160.5
to become 229161, which lasts until 229161.49999... I hope that's
clear.
The tropical year is defined as the mean interval between vernal
equinoxes;
that is the equinox of the northern hemisphere spring when the sun
crosses
from
the northern to the southern hemisphere (about March 20'th) and it thus
corresponds
to the seasons. It includes the effect of the precession of the pole.
That
is,
the tropical year differs by one part in 26,000 from the solar year as
one
precession
of the pole takes 26,000 years.
The paper by J. Laskar "Secular terms of classical planetary
theories
using the results of general theory," in Astronomy and Astrophysics
157,
59070 (1986)
gives an estimate for calculating the length of the tropical year in
days:
365.2421896698 - 6.15359E-6*T - 7.29E-10*T^2 + 2.64E-10*T^3
where T = (JD - 2451545.0)/36525 and JD is the Julian day number.
JD(2000,1,1) = 2451545, and dividing by 36525 approximates
centuries
so T = (Year - 2000)/100
However, the interval from a particular vernal equinox to the next
may
vary
from this mean by several minutes. This figure does not mean that the
year
changes its length, rather that the earth completes more or fewer
revolutions
in the circuit of one orbit. There is the drag caused by the continents
washing
into the tides raised by the moon and sun, but as well, there are mass
re-distributions on and within the earth; dynamic such as the swirlings
of
air
and water, and semi-static such as polar ice vs. equatorial ocean
height.
The leap-year rule for the Gregorian calendar amounts to taking the
year as
365 + 1/4 - 1/100 + 1/400 = 365.2425 days, 0.000310 days too
long.
An obvious adjustment and in the spirit of the others would be -
1/4000
but
this has yet to be agreed.
And applying the above formula gives a value for the tropical year
in
1582
of 365.242215 days, so 365.2425 is close.
}
var JD,Y,M,D,N,L: Longint;
Begin
JD:=IntRound(fj); {Note that Eurocentric astronomers like the day to
change at noon, GMT.}
L:= JD + 68569;
N:= 4*L div 146097;
L:= L - (146097*N + 3) div 4;
Y:= 4000*(L + 1) div 1461001;
L:= L - 1461*Y div 4 + 31;
M:= 80*L div 2447;
D:= L - 2447*M div 80;
L:= M div 11;
M:= M + 2 - 12*L;
Y:= 100*(N - 49) + Y + L;
L:=JD mod 7; {Locate the weekday.}
if Y < 1 then Y:=Y - 1; {Squeeze out year zero.}
WriteLn('Julian day number ',JD,' (mod 7 = ',L,',
',JulianWeekday[L],')',
' is Gregorian Date y',Y,'m',M,'d',D);
ElevenDayRiot(JD); {Warn about provenance.}
Greg:=Y + M/100 + D/10000; {NB! This is *not* a fraction of a year!}
End;
Function Julian(fj: number): number; {Julian calendar date from a
Julian
Day number.}
{ The Julian Day Number is a continuous run of days counted since the
nominal
first of January 4713BC on the extrapolated *Julian Calendar* for that
date,
and called "proleptic" since the Julian calendar didn't exist then.
This routine will return -4713/1/1 for JDay zero, remembering that
there
was no year zero, otherwise it would be -4712. The change is from JD
1721423
which is Friday, 31'st December 1BC (year -1) to JD 1721424 which is
Saturday,
1'st January 1AD as named by the Julian calendar as used *NOW* but not
then.
The Julian calendar is based on the analysis of the Egyptian
astronomer
Sosigenes and was introduced by Julius Caesar's command in 45BC,
creating
the
"year of confusion" when 90 days were inserted so as to return the
dates
to
their proper season for the new calendar.
Further confusion arose over the operation of the Julian calendar.
Leap
years
were applied every third year, so 45 BC, 42 BC, 39 BC, 36 BC, 33 BC, 30
BC,
27 BC, 24 BC, 21 BC, 18 BC, 15 BC, 12 BC, 9 BC were leap years. Then
Augustus
decreed a correction; no leap years until 8 AD, 12 AD, and every forth
year that
followed, except that there is dispute as to whether this had been
done,
and
who followed it or didn't in historical accounts being read now.
Keeping
the
calendar was a responsibility of the priests, who were open to bribes.
And
leap years were regarded as unlucky, so some were omitted. Not in
dispute
is that Augustus required that his month have as many days as did
Julius's
month...
Whichever, the Romans did not calculate with BC years or Ante
Christum,
but with AUC for Ab Urbe Condita, the founding of Rome by Romulus in
753BC,
though they were also not completely certain of their count. Thus the
divisibility of the Anno Domine year by four for leap years was by
chance.
So. Prior to 45AD the Julian calendar did not exist, but this
routine
assigns
date names as if it did and had been applied systematically, which it
wasn't.
There have been different dates for the last day of the year, so
although the
nominal Julian calendar now has December 31'st as the end of the year,
in various areas and times, the changeover was different. In England
the
year
began in March on the Julian calendar (when still in use) so January
1700/1701
written nowadays means 1700 on the Julian year, 1701 on the Gregorian
year.
The Byzantines used the first of September counting from the creation
in
5509BC.
We can't sneer, because we confuse matters with "astronomical years"
in
which
there is a year zero corresponding to 1BC, and others use a modified
'JD',
defined as MJD = JD - 2400000.5 so that MJD 0 thus begins on Wednesday
17'th
November 1858 (Gregorian) at 00:00:00 UTC, which day after noon would
have
a
Julian Day Number of 2400001.
NASA takes the prize, misusing the term Julian Day Number to denote
the
number of days since the first of January of the current year. Argh!}
var JD,i,j,k,l,n,Y,M,D: longint;
Begin
JD:=IntRound(fj); {See Procedure Greg.}
j:= JD + 1402;
k:= (j - 1) div 1461;
l:= j - 1461*k;
n:= (l - 1) div 365 - (l div 1461);
i:= l - 365*n + 30;
j:= 80*i div 2447;
D:= i - (2447*j div 80);
i:= j div 11;
M:= j + 2 - 12*i;
Y:= 4*k + n + i - 4716;
if Y < 1 then Y:=Y - 1; {There is no year zero. Year 1 is preceeded
by
year -1.}
l:=jd mod 7; {Locate the weekday.}
WriteLn('Julian day number ',JD,' (mod 7 = ',L,',
',JulianWeekday[L],')',
' is Julian Date ',Y,'/',M,'/',D);
Julian:=Y + M/100 + D/10000; {NB! This is *not* a fraction of a
year!}
End;
Function JDayJ(fy,fm,fd: number): number; {Julian Day Number from the
Julian calendar date.}
{ As with the civil usage, there is NO YEAR ZERO. 1AD is preceded by
1BC, and 1BC is to
be presented as Y = -1, *not* y = 0. A presentation of y = 0 will work
as
1BC in the
current scheme, but y = -1 will also appear as 1BC. If I change the
if-statements into
cunninng integer arithmetic, y = 0 will likely give odd results.}
var y,m,jd: longint;
const md: array[1..12] of integer =
(0,31,59,90,120,151,181,212,243,273,304,334);
Begin {Some analysis would concoct a crunch instead of this table.}
y:=trunc(fy); m:=trunc(fm); {These shouldn't have fractional parts.}
if y < 0 then y:=y + 1; {1BC is computationally more convenient as
year
0, divisible by 4}
y:=y + 4712; {Rebase. And avoid questions over exact behaviour
with
neg. numbers.}
JD:=365*y {Thus 4713BC (-4712 + 4712 = 0) is the starting year.}
+ y div 4 {Leap days that have lept. Note that y is positive.}
+ md[m]; {Passed month lengths, counting February as 28.}
if (y div 4 = 0) and (m > 2) then inc(JD); {Whoops, in this year a
leap
day has been passed.}
JDayJ:=JD + fd;
End;
Function Easter(fy: number):longint; {Easter Sunday for the nominated
year.}
{ Apparently first given by an anonymous correspondent from New York
to
Nature in 1876.
Samuel Butcher, Bishop of Meath, showed that this algorithm followed
from
Delambre's
analytical solutions, and produces the date of Easter for all
(Gregorian?)
years.
The Julian and Gregorian calendars have abandoned the attempt to
reconcile the
period of the moon (a "moonth") with the length of the year, but Easter
is
a remnant
of the time when moon-based calendars were preferred, and is a
fertility
rite aligned
with the (northern hemisphere) spring, thus the Easter bunny and Easter
eggs, and
is named from the mesopotamian goddess Ishtar.
Easter Sunday is the Sunday following the Paschal Full Moon date for
the year.
In June 325 A.D. astronomers approximated astronomical full moon dates
for
the Christian
church, calling them Ecclesiastical Full Moon dates. From 326 A.D. the
Paschal Full Moon
date has always been the Ecclesiastical Full Moon date that followed
March
20, which in
325AD was the equinox date.
The ecclesiastical Full Moon is defined as the fourteenth day of a
tabular lunation,
where day 1 corresponds to the ecclesiastical New Moon. The tables are
based on the
Metonic cycle, in which 235 mean synodic months occur in 6939.688 days.
Since nineteen
Gregorian years is 6939.6075 days, the dates of Moon phases in a given
year will recur
on nearly the same dates nineteen years laters. To prevent the 0.08 day
difference
between the cycles from accumulating, the tables incorporate
adjustments
to synchronize
the system over longer periods of time. Additional complications arise
because the tabular
lunations are of 29 or 30 integral days, the moon inconveniently
failing
to complete an
orbit in a round number of days. The astronomical moon, as observed,
might
easily start
a new moon before midnight in one location (local time) and after
midnight
in another,
and so a nominal moon position is used, based on tables adjusted for
"embolismic" lunations,
and the head spins.
The entire system comprises a period of 5,700,000 years of
2,081,882,250 days, which is
equated to 70,499,183 lunations. After this period, the dates of Easter
repeat themselves.
Except, by then the length of the day and the period of the moon
will
have changed...
Variations on this routine are common. Be careful if the mod
operation
might
be presented with negative numbers, as on some computers the results
will
not
be as expected. This routine does not involve any negative numbers, at
least
for positive years. Remember that this rule applies only from 326AD and
that
the Julian calendar was out of step with the seasons, leading to the
introduction
of the Gregorian calendar. As well, different churches defined Easter
differently.
}
var a,Century,yy,d,e,f,g,h,i,k,l,m,p: longint;
var Year,EasterMonth,EasterSunday,JD: longint;
Begin
year:=Trunc(fy);
a:=year mod 19; {a + 1 = GoldenNumber}
Century:=year div 100;
yy:=year mod 100;
d:=Century div 4;
e:=Century mod 4;
f:=(Century + 8) div 25;
g:=(Century - f + 1) div 3;
h:=(19*a + Century - d - g + 45) mod 30; {Extra +30 to ensure no
confusion over (neg) mod.}
i:=yy div 4;
k:=yy mod 4;
l:=(32 + 2*e + 2*i - h - k) mod 7; {32 + etc. prevents negative
numbers.}
m:=(a + 11*h + 22*l) div 451;
EasterMonth:=(h + l - 7*m + 114) div 31;
p:=(h + l - 7*m + 114) mod 31;
EasterSunday:=p + 1; {Day in Easter Month.}
writeln('Easter Sunday ',year,'/',EasterMonth,'/',EasterSunday);
JD:=Trunc(JDay(Year,EasterMonth,EasterSunday));
ElevenDayRiot(JD);
Easter:=JD;
End;
{--------------------------Enough date
complications!-------------------------}

Free eBook - Interview Questions: Get over 1,000 Interview
Questions in an eBook for free when you join JobsAssist. Just click on the
button below to join JobsAssist and you will immediately receive the Free eBook
with thousands of Interview Questions in an ebook when you join.