Add to Favorites    Make Home Page 29376 Online  
 Language Categories  
 Our Services  

Home » Pascal Home » Pascal Projects Home » Calendar date to day number and back


Search Projects & Source Codes:

Title Calendar date to day number and back
Author Nicky McLean
Author Email RNMcLean [at]
Description Functions that, given a calendar date (Gregorian or
Julian), calculate a day number (the Julian day number), and
Just for fun, given a year number, calculate Easter Sunday's date.
These routines are the only sensible way to calculate the day of the
week, the number of days between two dates, or the date some number of days after a given date, etc.
Category Pascal » Pascal Projects
Hits 12279
Code Select and Copy the Code
{--------------------------------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!-------------------------}

Related Source Codes

Script Name Author
Matrix Multiple Cirruse Salehnasab
Function Power Recursive Cirruse Salehnasab
swim brian colston
tetris (Mini Project) mehdi farrokhzad
Macsi - space fighting game. Macsi PÚter
Recursive Monkey Puzzle Solution - Project Maxim C.L. Wrne
Maze Game Project In Pascal Mahmood
Excellent Rat in a Maze Program. VyomWorld
A car game. You have to drive the car in such a way that you dont strike a barrier on the road. VyomWorld
Student Database Information System. VyomWorld
Tic Tac Toe Game implemented in Pascal. VyomWorld
Game to Gain more blocks by drawing appropriate lines from correct places(dots). VyomWorld
To Find The Coinage Of The Amount Entered. VyomWorld
Randomizes two 3x3 arrays and indicates the numbers whih are common in both the arrays otherwise an cross 'x' is shown instead. VyomWorld
Program that checks the space on drive a: and also gives a graphical representation of memory. VyomWorld


Google Groups Subscribe to SourceCodesWorld - Techies Talk

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.

New! Click here to Add your Code!

ASP Home | C Home | C++ Home | COBOL Home | Java Home | Pascal Home
Source Codes Home Page


Google Search


Source Codes is a part of Vyom Network.

Vyom Network : Web Hosting | Dedicated Server | Free SMS, GRE, GMAT, MBA | Online Exams | Freshers Jobs | Software Downloads | Interview Questions | Jobs, Discussions | Placement Papers | Free eBooks | Free eBooks | Free Business Info | Interview Questions | Free Tutorials | Arabic, French, German | IAS Preparation | Jokes, Songs, Fun | Free Classifieds | Free Recipes | Free Downloads | Bangalore Info | Tech Solutions | Project Outsourcing, Web Hosting | GATE Preparation | MBA Preparation | SAP Info | Software Testing | Google Logo Maker | Freshers Jobs

Sitemap | Privacy Policy | Terms and Conditions
Copyright ©2003-2017, All Rights Reserved.
Page URL:

Download Yahoo Messenger | Placement Papers | Free SMS | C Interview Questions | C++ Interview Questions | Quick2Host Review