Gregorian day numbers By , journalist and programmer |
|
In case calendar dates are a substantial part of a computer application, the programmer who creates it can hardly omit a well working day numbering system. After all, calendar dates in themselves are not ready-made to do easy math on. Only when dates are converted to numbers (and those numbers are in sequence!) calculations on dates become rather easy. The only question is: which of the daynumbering algorithms fits best? | |
I'm proud to announce that since today you've one additional choice in this respect, the Gregorian Day Number. As its name points out, the Gregorian Day Number algorithm fits in the Gregorian Calendar which we use today. Before I come to explain it, I like to discuss a few existing systems in order to see their possible drawbacks.
Julian Day Number Native Windows' daycount A few lines of history In the Julian Calendar every fourth year was a leap year. On behalf of Pope Gregory's astronomers this rule was changed as follows: every fourth year is a leap year except years that can be evenly divided by 100 (the so called century years), unless they can (also) be divided by 400. Thus, 1600 was a leap year and so was recent 2000, but 1700, 1800 and 1900 were not, nor will 2100, 2200 and 2300 be. You may also put it this way: a period of 4 centuries does not count 100 leap years, but 97. To bring the calendar in line with the new leap year rule, 10 days were 'eliminated': October 15, the first day of the Gregorian Calendar, followed October 4 in the abandoned Julian Calendar. In fact those 10 days were approximately no more and no less than the false leap days that had 'polluted' the calendar in past century years. Because the Gregorian Calendar was proclaimed by 'a roman catholic pope', it was not immediately implemented everywhere. Authorities in protestant regions were sometimes reluctant for ages and so were Russian Orthodox prelates. In Russia the new calendar was accepted in the 20th century, after the communist party took power in what was then called The Soviet Union. The old Julian Calendar was 13 days out of sync by that time, so the soviets had to skip 13 days. That explains why the Russians always commemorate their October Revolution in November. The formula In order to convert a date in the Gregorian Calendar to a Gregorian Day Number, a few simple rules apply: This is the Gregorian FUNCTION (parameters: year, month and day) in human language. First thing to do is to check the month. If it is January or February [in code: IF month < 3] we add 12 to make January the 13th or February the 14th month. This not only moves February to the tail of the month sequence but also makes a leap day the last day of the year. Beware: both, January and February, are considered to be months of the previous year, so we have to substract one from the year variable as well.
To do it the other way, i.e. to convert a number back to the date it represents, you should consider: ![]() ![]() ![]() The formula is contained in a procedure (SUB) of which GDN - Gregorian Day Number - is the input parameter, while year, month and day are output parameters. For the time being you should construct the date format, such as "mm-dd-yyyy", from these values yourself. Almost all the calculations in the SUB are based upon the elimination of fully elapsed days. As said, our years should begin on March 1. To achieve this, we need to alter the base of the day number passed. Its original base is 10/15/1582 = 1. If we add 614565 days, its base will become: 03/01/-0100 = 1 (614565 is the number of days between March 1, -100 and October 15, 1582 AD). A predictable question is: why extend our computation that far backward? Don't ask me, I don't know. Starting in years closer to 1582, which I certainly would prefer, did not work correctly during the many hours I've spent to test this algorithm. Once we have altered the base of our computations, we can calculate the number of centuries that have fully elapsed since March 1, -100. Four centuries count, as said earlier, exactly 146097 days (400 times 365 plus 97 leap days). So, if we multiply our modified input by 4 and divide the result by 146097, we get the number of elapsed centuries. We also can find the number of days in those centuries: 146097 times centuries divided by 4 (CEIL rounded). Substract those days from the initial value (i.e. input + 614565) and we have eliminated the days in the fully elapsed centuries. Our pseudo code so far: What remains after eliminating the days in elapsed centuries is undoubtedly the number of days in the century of date. The next step is to get the number of elapsed years within that century. Piece of cake: multiply the remaining days 4 times and divide the result by 1461 days. Once done, we can get the number of days in those years and eliminate them as well. In code: In the previous step we have seen that we did'nt eliminate all the days in elapsed years. We kept 31 'in stock'. These extra 31 days have to do with the odd month sequence (March = month 1) we are following here. In the meantime we know how many centuries have passed by since March 1, -100 and how many years there are in the current century (0 - 99). Using those data, we can construct the 4-digit year. By using '(centuries - 1)' the 100 years before zero are skipped correctly. The final step is to get the month and eliminate the days in fully elapsed months. What remains then is the number of days in the month of date (= day in month). The formula used here looks a bit strange, but 2447 days divided by 80 gives an average of approximately 30.6 days per month: Is this really the end? Not quite, because we have to restore the month sequence back to normal, so we add 2. This sets March (was 1) to 3 .... December to 12, but, unfortunately, also: January to 13 and February to 14. In order to correct this we simply use the routine the Gregorian FUNCTION started with (only in the opposite way): More to come Thanks |
|
Where to download? |