# Calendrical Calculations for the Revised Julian Calendar

Created by Dr. Irv Bromberg, University of Toronto, Canada

## Join the Calendars LISTSERV

The pseudocode calendrical calculations presented here are adapted from Gregorian and Julian calendar functions published by Reingold and Dershowitz, although those authors explicitly ignored the Revised Julian calendar (see page 57, footnote 4 in Calendrical Calculations: The Ultimate Edition, referred to hereinafter as CC4).

In the course of adding the Revised Julian calendar to my freeware Kalendis calendrical calculator, I found that there were no published sources for implementing its calendrical calculations, and that it is impossible to reproduce the published dates for this calendar unless its proleptic epoch is set equal to that of the Gregorian calendar.

This web page is freely and unconditionally presented in the public domain for anyone who wishes to implement the necessary functions for any purpose.

## Introduction to the Revised Julian Calendar

For the history, correspondence to the Julian and Gregorian calendars, Easter controversies, list of countries and churches that have adopted this calendar and when, and criticism, please see the Wikipedia article here: https://en.wikipedia.org/wiki/Revised_Julian_calendar.

The Revised Julian calendar was first proposed at the 1923 Orthodox Church synod by Serbian scientist Milutin Milankovitch.

In 900 Julian years there are 900/4 = 225 leap days, but the Revised Julian leap rule omits seven of nine century leap years, leaving 225 − 7 = 218 leap days per 900-year cycle. Thus the calendar mean year is 365 + 218/900 days, but this is actually a double-cycle that reduces to 365 + 109/450 = 365.242 days, or exactly 365 days 5 hours 48 minutes 48 seconds, which is exactly 24 seconds shorter than the Gregorian mean year of 365.2425 days, so in the long term on average the Revised Julian calendar pulls ahead of the Gregorian calendar by 86400 seconds per day / 24 seconds per year = 3600 years per day difference.

The number of days per Revised Julian cycle = 900 years × 365 days per common year + 218 leap days = 328,718 days. Taking this mod 7 leaves a remainder of 5, so like the Julian calendar, but unlike the Gregorian calendar, the Revised Julian calendar cycle does not contain a whole number of weeks. Therefore, a full repetition of the Revised Julian leap cycle with respect to the seven-day weekly cycle is seven times the cycle length = 7 × 900 years per cycle = 6300 years.

Instead of developing a fixed arithmetic Easter computus having a mean year equal to that of the Revised Julian Calendar, the synod proposed adoption of an astronomical rule (see the detailed criteria specified in the paragraph starting with The synod also proposed on the Wikipedia page at https://en.wikipedia.org/wiki/Revised_Julian_calendar). Nevertheless, apparently because of a lack of authoritative consensus regarding the specific criteria to employ for such calculations, and perhaps the inherent uncertainties of astronomical calculations (especially when a variety of methods are compared), most Orthodox Churches continue to use the Easter computus of the Julian calendar, ignoring the problem that its mean year is 11 minutes and 12 seconds longer than the mean year of the Revised Julian calendar, and a few Orthodox Churches use the Gregorian Easter computus, ignoring the problem that its mean year is 24 seconds longer than the mean year of the Revised Julian calendar.

Easter is a feast, not a planet. You do not determine it to hours, minutes and seconds. — Johannes Kepler, 1613 (see here, page 40 at the bottom, 195.)

## Epoch

The proleptic epoch of the original Julian calendar was on the Saturday before the Monday that was the epoch of the Gregorian calendar. In other words, Gregorian 1 January 1 AD = Julian 3 January 1 AD.

The Revised Julian reform, however, not only changed the leap rule but also made the epoch the same as that of the Gregorian calendar. This seems to have been carried out implicitly, and even scientific articles made no mention of this epoch shift.

Nevertheless, it is impossible to implement calendrical calculations and calendar date conversion software without appreciating this detail and taking the 2-day shift (with respect to the original Julian calendar) into account. If the original Julian calendar epoch is mistakenly used in such calculations then there is no way to reproduce the currently accepted dating of the Revised Julian calendar, which yields no difference between Gregorian and Revised Julian dates from the 17th to the 28th centuries and most other centuries since the start of the Christian era (including the two first), assuming that both calendars start dates at Local Mean Midnight.

## Northward Equinox (Northern Hemisphere Vernal Equinox, March Equinox)

The following is a scatter plot of actual astronomical northward equinox moments as numerically integrated by SOLEX 11 using DE421 mode with extended (80-bit) floating point precision, high integration order (18th order), and forced solar mass loss (forced means taken into account at all times). SOLEX can automatically search for northern hemisphere spring equinox moments by finding when the solar declination crosses the celestial equator in the northward direction, and then it outputs that data as the Terrestrial Time (TT) day and fraction of day relative to 1 January 2000 at noon (J2000.0 epoch = Julian Day 2451545.0 = Rata Die 730120.5). The progressive tidal slowing of the Earth rotation rate was accounted for by subtracting ΔT as calculated by the Espenak-Meeus polynomial set recommended at the NASA Eclipses web site to obtain the J2000.0-relative Universal Time (UT) moments, which were then properly converted to Revised Julian dates and Jerusalem local apparent time, taking local apparent midnight as the beginning of each calendar day. The year range of the chart was limited to dates before the year 4400 AD, because by then ΔT is expected to accumulate to about six hours, with an uncertainty of less than 2+1/2 hours.

The chart shows that the average long-term astronomical equinox drift of the Revised Julian calendar is small, at least until 4400 AD. Aside from astronomical drift of the equinox, the cycle's medium-term wobble (jitter) spans 2+163/450 days = 2.362 days because the leap years of the Revised Julian calendar are not distributed as smoothly as possible: they regularly occur at 4-year intervals but there are 8-year gaps at 7 of 9 centurial years in each cycle. Compare this with the Gregorian calendar jitter = 2+79/400 days = 2.1975 days, which is less because it has only 400 years per cycle and only one 8-year gap per cycle. The minimum possible jitter for a reduced leap day solar calendar is one day minus 1/(years per cycle) of a day, for example the original Julian calendar jitter is only 4 − 1/4 = 3/4 day = 0.75 day (on the other hand, the astronomical equinox rapidly drifts through the original Julian calendar at a rate of about one calendar day earlier per 130.90 years because its calendar mean year is about 11 minutes longer than the mean northward equinoctial year).

## Overview of Revised Julian Calendrical Calculations

Refer to CC4 methods for handling BC dates and the traditional omission of a year zero, both of which are ignored here. As a consequence, using the calendrical calculations presented herein, the year prior to 1 AD was year zero, and dates before year zero yield negative year numbers.

CC4 defines the MOD operator as x MOD y = modulus( x, y ) = xy × floor( x / y ), because that expression is valid for negative and floating point operands, returning the remainder from dividing x by y while discarding the quotient (see the modulus function in CC4 on page 21 at the top, equation 1.17). Expressions like floor( x / y ) return the quotient from dividing x by y while discarding the remainder.

If you wish to copy/paste programming code from this web page into a computer program note that certain symbols, used for appearance sake, need to be adjusted: convert × to *, convert − to -, and extra spaces included for readability may be automatically dropped by the program editor. Pay attention to how funtions return results in your chosen programming language, especially for the case where multiple values are returned together: { year, month, day }. I have intentionally employed undeclared self-documenting verbose variable names.

## Fixed Days (ordinal day numbers relative to an epoch)

Calendrical calculations are made consistent and straightforward for arithmetic operations if dates are first converted to an ordinal number of days relative to an agreed-upon epoch, in this case the Revised Julian epoch, which was the same as the Gregorian epoch. To find the difference between any two Revised Julian dates, convert both to ordinal day numbers and simply subtract. To find a past or future date, convert a given date to an ordinal day number, subtract or add the desired number of days, then convert the result to a Revised Julian date.

The calendrical calculation functions given here will not crash if an invalid date is given. To verify that a given date is a valid Revised Julian date, convert it to an ordinal day count and then back to a Revised Julian date — if the final date differs from the given date then the given date is invalid. This method should also be used to validate any implementation of calendrical calculations, by iteratively checking thousands of random and sequential dates for such errors.

To convert a Revised Julian date to any other calendar, first convert it to an ordinal day number, and then all that is needed is a function to convert the ordinal day number to that calendar. To convert a date from any other calendar to a Revised Julian date, first convert that calendar date to an ordinal day number, then convert the ordinal number to the Revised Julian date.

The following constant defines midnight at the start of (proleptic) Revised Julian date Monday, 1 January 1 AD as the beginning of the first ordinal day. This moment was Julian day number 1721425.5:

CONSTANT RJepoch = 1

CC4 outlines functions for Gregorian and Julian calendar conversions, as well as many other calendars, always calculating in terms of the ordinal day number, which they call the fixed date or rata die (RD), assigning the number 1 to the Gregorian calendar epoch. The arithmetic herein, by using the same ordinal day numbering epoch, is fully compatible with all CC4 functions for calendrical calculations and date inter-conversions.

One can assign a different integer to the Revised Julian epoch, for the purpose of numbering ordinal days relative to some other epoch, but if you do so then you must always take the epoch difference into account when using any CC4 calendar functions and when converting an ordinal day number to a weekday number.

Optionally the ordinal day number can include a fractional component to represent the time as the elapsed fraction of a day. For example, the ordinal day number of the J2000.0 moment (1 January 2000 AD at Noon) was 730120.5.

## Check for Leap Year

• FUNCTION isLeapYear( year ) ' this logic avoids a nested IF
•
• IF year MOD 100 = 0 THEN ' check for centurial year
•
• Century = (year / 100) MOD 9
• ' century years are common years except for the 2nd and 6th centurial years per cycle
• isLeap = (Century=2) OR (Century=6)
•
• ELSE ' non-centurial year is leap only if divisible by 4
•
• isLeap = (year MOD 4 = 0)
•
• END IF
•
• RETURN isLeap
•
• END FUNCTION

## Convert a Revised Julian Date to Fixed Days

Convert a Revised Julian date { year, month, day } to the corresponding unique fixed day number. Note that RJepoch is offset by subtracting one, but we explicitly include it so that RJepoch can be assigned a value other than one for an alternate ordinal day numbering scheme:

• FUNCTION RevisedJulianToFixed( year, month, day )
•
• PriorYear = year − 1
• FixedDays = RJepoch + 365 × PriorYear + floor(PriorYear / 4) + floor((367 × month − 362) / 12) + day − 1
•
• ' If month is after February then subtract 1 day for a leap year or subtract 2 days for a common year:
• IF month > 2 THEN
• IF isLeapYear(year) THEN FixedDays = FixedDays − 1 ELSE FixedDays = FixedDays − 2
• END IF
•
• ' Finally subtract a day for each prior century year (most of which are non-leap) and then add back in the number of prior century leap years:
• PriorCenturies = floor(PriorYear / 100)
• FixedDays = FixedDaysPriorCenturies + floor((2 × PriorCenturies + 6) / 9)
•
• RETURN FixedDays
•
• END FUNCTION

## Convert Fixed Days to a Revised Julian Date

Convert an ordinal day number to the corresponding Revised Julian { year, month, day }. Note that subtracting RJepoch is here offset by adding one, but we explicitly include it so that RJepoch can be assigned a value other than one for use with an alternate ordinal day numbering scheme:

• FUNCTION FixedToRevisedJulian( FixedDays )
•
• ' start by removing any fractional time-of-day portion:
• Days = floor(FixedDays) − RJepoch + 1
•
• PriorCenturies = floor(Days / 36524)
• RemainingDays = Days − 36524 × PriorCenturiesfloor((2 × PriorCenturies + 6) / 9)
• PriorSubcycles = floor(RemainingDays / 1461)
• RemainingDays = RemainingDays MOD 1461
• PriorSubcycleYears = floor(RemainingDays / 365)
• year = 100 × PriorCenturies + 4 × PriorSubcycles + PriorSubcycleYears
• RemainingDays = RemainingDays MOD 365
•
• IF RemainingDays = 0 THEN
• ' This is either the 365th day of a common year, or the 365th or 366th day of a leap year.
• ' Either way, we have to decrement the year because we went one year too far:
• year = year − 1
• IF isLeapYear(year) AND PriorSubcycles=0 THEN RemainingDays=366 ELSE RemainingDays=365
• END IF
•
• PriorDays = RemainingDays − 1
• IF isLeapYear(year) THEN correction = 1 ELSE correction = 0
• IF PriorDays < (31 + 28 + correction) THEN correction = 0 ELSE correction = 2 − correction
• month = floor((12 × (PriorDays + correction) + 373) / 367)
•
• ' Finally, calculate the day number within the month
• ' by subtracting the Fixed days count for the start of the month from
• ' the originally given Fixed days count and then add one day:
• day = FixedDaysRevisedJulianToFixed(year, month, 1) + 1
•
• RETURN { year, month, day }
•
• END FUNCTION

## Determine the Weekday

Convert the ordinal number of days since the Revised Julian epoch to a weekday number (Sunday=1 through Saturday = 7):

• FUNCTION WeekdayNumber( FixedDays )
•
• RETURN ( floor(FixedDays) − RJepoch + 1 ) MOD 7 + 1
•
• END FUNCTION

The calendar epoch is explicitly included here so that alternative ordinal day numbering schemes can be employed. Don't be tempted to omit subtracting the RJepoch just because it is offset by adding +1. As written, this expression is robust even if you assign a value other than one to the epoch.

Updated Aug 15, 2024 (Symmetry454) = Aug 13, 2024 (Symmetry010) = Aug 12, 2024 (Revised Julian) = Aug 12, 2024 (Gregorian)