DATE ±ISOymd = 20170429 = 2017 04 29 = 2017 April 29 (Gregorian Calendar) = Saturday JD = 2457873 = Standard Gregorian JD number for the date DoWDate = 6 = Saturday DoW1 = 6 = Saturday (DoW of 1st day of April) mDays = 30 days in April For April of 2017 (Gregorian), we would construct a 30-day calendar beginning on a Saturday. --------------------- G 2017 April Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 --------------------- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||

| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||

The BASICS OF MAKING A STANDARD CALENDAR FOR ANY DATETo construct a calendar for any given date, we can break down the process into 4 essential steps. - Compute the standard calendrical JD number for the given date.
- Determine the day of the week on which the given date falls.
- Determine the day of the week on which the month containing the given date begins.
- Determine the number of days in the month containing the given date.
Step 1:
Compute The Standard Calendrical JD (Julian Day) Number For the Given Date
NOTE:Here, the calendrical JD number is being distinguished from the astronomical JD number in that the time of day is ignored. The calendrical JD number simply serves its original purpose as a unique, linear, integer serial number, one for each date on the standard calendar. There are some rare historical deviations from the standard calendar formula, but those special cases are not being considered here.
The JD number is the single most important number we will use for a variety of general Julian and Gregorian calendar computations. It contains all the information we need to create a complete standard calendar for any month of any year over a very long time period extending thousands of years into the past, prior to the actual dates either calendar officially existed, as well as thousands of years into the theoretical future. To construct a calendar, we begin by computing the simple calendrical JD (Julian Day) number for the given calendar date and calendar mode. This simple calendrical JD number will always equate to a positive integer value, measured forward from origin `JD=0` in the distant past.
The prehistoric mathematical origin of the Julian calendar model is: `JD=0` on `4713 BC Jan 01 = Monday`
The prehistoric mathematical origin of the Gregorian calendar model is: `JD=0` on `4714 BC Nov 24 = Monday`
Since each calendar system begins with `JD=0` being on a Monday and every `7` th day thereafter is a Monday, this leads to a simple formula to derive the day of the week (DoW) directly from the JD number. This formula will follow later. We have to compute the JD number first of all.
In the simplest terms, the JD number for any given date is the serial count of the number of days on the calendar that have passed to date since the mathematical origin of the respective calendar system model. For example, the current Universal Gregorian Date is: `2017 Apr 29` , for which `JD=2457873` , which means that today is sequential calendar day number `2457873` , as reckoned from the mathematical origin (`JD=0` ) of the Gregorian calendar system that began on Monday, November 24th, 4714 BC.
Every date on the calendar has such a unique JD serial number reckoned from the origin. Since it works like a linear yardstick, the difference between the JD numbers of any two dates equates to the exact number of calendar days between those two dates, which includes accounting for any leap years in between as well.
Compute the simple calendrical JD (Julian Day) number for any given integer-encoded date and calendar mode. The numerical value of this JD number will always equate to a positive integer value.
`ISOymd = ` ISO integer-encoded date value (Negative = BC date)`CalMode = ` Calendar mode (`0=Julian` or `1=Gregorian` )
YearSignVal = (ISOymd < 0)? -1 : 1 u = abs(ISOymd) v = floor(u / 10000) y = YearSignVal * v m = floor((u - 10000*v) / 100) d = u - 10000*v - 100*m w = (y < 0)? y+1 : y a = floor((14-m) / 12) b = w - a c = floor(b/100) JD = floor(30.6001*(12*a + m + 1)) + floor(365.25*(b + 4716)) - 1524 + CalMode*(floor(c/4) - c + 2) + d JD EXAMPLE: For the interface date entered above. ISOymd = 20170429 = 2017 April 29 CalMode = 1 (Gregorian) ----------------------------------------------------------- YearSignVal = ((2017 < 0)? -1 : 1) = 1 u = abs(20170429) = 20170429 v = floor(20170429 / 10000) = 2017 y = 1 * 2017 = 2017 m = floor((20170429 - 10000*2017) / 100) = 4 d = 20170429 - 10000*2017 - 100*4 = 29 w = ((2017 < 0)? 2017+1 : 2017) = 2017 a = floor((14-4) / 12) = 0 b = 2017 - 0 = 2017 c = floor(2017/100) = 20 JD = floor(30.6001*(12*0 + 4 + 1)) = 153 + floor(365.25*(2017 + 4716)) - 1524 = 2457704 + 1*(floor(20/4) - 20 + 2) + 29 = 16 = 153 + 2457704 + 16 = 2457873 Step 2:
Determine the Day of the Week (DoW) On Which the Given Date Falls
From the calendrical JD serial number for the given date, we can determine the corresponding day of the week (DoW) index. This is simply a number code from 0 to 6, interpreted to represent the days of the week from Sunday to Saturday respectively. The formula is based on the fact that both calendar system models begin ( `JD=0` ) on a Monday (`DoW=1` ), by definition, and reckoned cyclically forward from there, every `7` th day is a Monday.
Compute the day-of-the-week (DoW) index from the standard Julian Day (JD) number. The same formula applies to both the Julian and Gregorian calendars.
` JD = ` Calendrical JD number for given date`DoW = ` Day of the week index code corresponding to JD
DoW = (JD + 1) mod 7 Where the DoW indices are:
0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri and 6=SatDoW EXAMPLE: For the interface date entered above. ISOymd = 20170429 = 2017 April 29 (Gregorian Calendar) JD = 2457873 DoW = (JD + 1) mod 7 = 2457874 mod 7 = 6 = Saturday Step 3.
Determine the Day of the Week On Which the Month Containing the Given Date Begins
Given the day of the month and its corresponding day of the week index, we can proceed to find the day of the week on which the month containing the given date begins. The following algorithm applies equally to both the Julian and Gregorian calendar systems.
Given the day of the week index corresponding to any given date, compute the day of the week on which the month containing the given date begins.
`d = ` Day of the month (`1` to `31` )`DoWDate = ` DoW of the given date (d)`DoW1 = ` DoW of 1st day of the month containing the given date
DoW1 = (DoWDate + 7 - ((d-1) mod 7)) mod 7 Where the DoW indices are:
0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri and 6=SatDoW1 EXAMPLE: For the interface date entered above. ISOymd = 20170429 = 2017 April 29 (Gregorian Calendar) d = 29 DoWDate = 6 = Saturday DoW1 = (DoWDate + 7 - ((d-1) mod 7)) mod 7 = (6 + 7 - (28 mod 7)) mod 7 = 6 = Saturday On the Gregorian calendar: If April 29, 2017 is Saturday, then that month begins on a Saturday. Step 4.
Determine the Number of Days in the Month Containing the Given Date
In practice, every month has a constant number of days, either 30 or 31 days, with the exception of February, which has 28 days or, in the case of a leap year, 29 days. One simple way of creating a function to return the number of days in a given month, is to store the number of days in an indexed array ( `i=0` to `m-1` ). Then, given the month number (m), we can fetch the corresponding number of days directly from the array.
By this scheme, the number of days in the month of September ( `m=9` ) could be symbolized as`mDays = DaysInMonth[m-1] = DaysInMonth[i] = DaysInMonth[8] = 30`
Then there is the leap year adjustment to be made for February, when applicable. Two different approaches will be considered here. One uses the number of days stored in an array, as mentioned above, and the other method is a purely logical formulation based on a simple fortuitous pattern found in the source data and translated into an algorithm.
Get the number of days in any given month of any given year. The number of days in the months are held in an indexed array, from which the values can easily be extracted according to the numerical value of the month. For leap years, a special adjustment is made for February.
`DaysInMonth = ` Indexed array holding the number of days in each month` y = ` Year (Negative = BC)` m = ` Month number (`1` to `12` )` leap = ` Leap year flag (`1=Leap` or `0=Common` )` mDays = ` Number of days in given month of given yearDaysInMonth = array (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) mDays = DaysInMonth[m-1] w = (y < 0)? y+1 : y if (CalMode == 0) { leap = (w mod 4 == 0)? 1:0 } else { leap = ((!(w mod 4) && (w mod 100)) || !(w mod 400))? 1:0 } if (m == 2 && leap == 1) {mDays = 29} This does the same as the above, but using a more direct algorithmic approach, without using any array. w = (y < 0 )? y+1 : y if (CalMode == 0) { leap = (w mod 4 == 0)? 1:0 } else { leap = ((!(w mod 4) && (w mod 100)) || !(w mod 400))? 1:0 } mDays = 30 - ((m < 8)? -1:1)*(m mod 2) + floor(m/8) - ((m == 2)? 2:0) + ((m == 2 && leap == 1)? 1:0) SUMMARY
The above algorithms provide the foundation for creating a simple perpetual calendar program. DATE ±ISOymd = 20170429 = 2017 04 29 = 2017 April 29 (Gregorian Calendar) = Saturday Putting the above algorithms together, we determine: JD = 2457873 = Standard Gregorian JD number for the date DoWDate = (JD + 1) mod 7 = DoW of the given date = 2457874 mod 7 = 6 = Saturday DoW1 = (DoWDate + 7 - ((d-1) mod 7)) mod 7 = DoW of 1st day of April = (6 + 7 - (28 mod 7)) mod 7 = 6 = Saturday mDays = 30 days in April For April of 2017 (Gregorian), we would construct a 30-day standard calendar beginning on a Saturday. --------------------- G 2017 April Su Mo Tu We Th Fr Sa 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 --------------------- |