- Convert the Julian Day Number to the number of days from some base date.
- Determine the number of years from the base date.
- Calculate the number of remaining days once the years are accounted for.
- Determine the month number represented by the remaining days.
- Calculate the number of remaining days once the months are accounted for.

The Julian Day Number is converted to the number of days from a base date of March 1 in the year zero. This creates a calendar with January and February as months 13 and 14 rather than months 1 and 2. The purpose of this scheme is to cause any extra day in a leap year to occur at the end of the "year." As will be seen, this simplifies the calculation of the number of leap years from year zero to a particular date and it simplifies the function which relates the number of days in the preceding months to the month number.

Let MOD be the modulo function. Gregorian year Y is a leap year if Y MOD 4 = 0 and if Y MOD 100 = 0 then it is also required that Y MOD 400 = 0. In our year starting on March 1, the days in a any January 1 based year span two different March 1 based year numbers. For example, if February 29 is in year Y for a year beginning January 1, it is in year Y-1 for a year beginning March 1. Similarly, to see if there is an extra day due to a leap year in year Y of a calendar beginning March 1, then our Gregorian leap year test must be applied to year Y+1.

From Table 2, it can be seen that in order to convert our Julian Day Number to the number of days since March 1 of the year zero in the Gregorian calendar, 1721119.5 must be subtracted. If day 1 is to be **on** March 1 of the year zero in the Gregorian calendar, 1721118.5 would be subtracted.

The number of days accounted for by a span of Y years, although equal to 365*Y+[Y/4] -[Y/100]+[Y/400], is approximately equal to 365*Y+Y/4 -Y/100+Y/400 = 365.2425 since the greatest integer function changes the value of its argument by less than 1. If D is the day number of year Y with values 1 through 365 (or 366 if a leap year), then the task is to find Y given

365*Y+[Y/4] -[Y/100]+[Y/400] + D days.

Y must then be approximately

INT((365*Y+[Y/4] -[Y/100]+[Y/400] + D)/365.2425)

Examing the error from this approximation:

INT((365*Y + [Y/4] - [Y/100] + [Y/400] + D)/365.2425)

=INT((365/365.2425)*Y + ([Y/4] - [Y/100] + [Y/400] + D)/365.2425)

=INT((365/365.2425)*Y + ([Y/4] - [Y/100] + [Y/400] + D)/365.2425 + (Y/4 - Y/100 + Y/400)/365.2425 - (Y/4 - Y/100 + Y/400)/365.2425)

=INT((365*Y)/365.2425 + ([Y/4] - [Y/100] + [Y/400] + D)/365.2425 + (Y/4 - Y/100 + Y/400)/365.2425 - (Y/4 - Y/100 + Y/400)/365.2425)

=INT((365*Y + (Y/4 - Y/100 + Y/400))/365.2425 + ([Y/4] - [Y/100] + [Y/400] - (Y/4 - Y/100 + Y/400) + D)/365.2425)

=INT((365.2425*Y)/365.2425 + ([Y/4] - Y/4 - [Y/100] + Y/100 + [Y/400] - Y/400 + D)/365.2425)

=INT(Y + ([Y/4] - Y/4 - [Y/100] + Y/100 + [Y/400] - Y/400 + D)/365.2425)

=Y + INT(([Y/4] - Y/4 - [Y/100] + Y/100 + [Y/400] - Y/400 + D)/365.2425)

The difference between Y and this approximation is our error function and is equal to

INT(([Y/4] - Y/4 - [Y/100] + Y/100 + [Y/400] - Y/400 + D)/365.2425)

Note that the difference function has the same value if a multiple of 400 is added to Y; i.e. only the values of Y modulo 400 with values between 0 and 399 need be examined when the error function is evaluated.

Unfortunately, the error function has a minimum value of -0.001301274553891091 at Y modulo 400= 303 ( a leap year) and D = 1. The error function has a maximum value of 1.001973218175465 at Y modulo 400 = 95 (a leap year) and D = 366. Since the difference between maximum and minimum values is greater than 1, a constant can not be subtracted to make our error function go to zero.

The values that are out of range could be special cased or corrections applied once the number of days contained in the years from the base date are subtracted. Instead, the approach taken here is to determine either the number of full centuries represented by the time span or the number of full 400 year periods. This allows the values [Y/100] and [Y/400] to be eliminated in the difference function and this creates a function that is better behaved.

Let Y be the year (for years starting March 1) of our given date. Then [Y/100] is the number of full centuries and the value to be determined given the number of days between base and target date. Since the number of full century years is to be determined given the days since our base date and there are 365.2425*100 such days per century, consider the difference between [Y/100] and

INT(INT((365*Y + [Y/4] - [Y/100] + [Y/400] + D)/365.2425)/100)

=INT((365*Y + [Y/4] - [Y/100] + [Y/400] + D)/(100*365.2425))

In particular, the difference function equal to

-[Y/100] + ((365*Y + [Y/4] - [Y/100] + [Y/400] + D)/(100*365.2425))

is examined.

First, notice that this difference function has the same value if a multiple of 400 is added to Y; i.e., only the values of Y modulo 400 with values between 0 and 399 need be examined. This difference function is our error function and it has a minimum value of 0.000006904926745444993 when Y mod 400 = 300 (not a leap year), D=1. The error function has a maximum value of 1.000000080212121 when Y mod 400 = 399 (a leap year), D=366. In order for our approximation to be valid, the error function must have values that are greater than or equal to 0 and less than 1 so that applying the greatest integer function to it produces a result of zero. This can be done by subtracting a constant K:

((365*Y + [Y/4] - [Y/100] + [Y/400] + D - K)/(100*365.2425))

This requires

K/(100*365.2425) > 1.000000080212121 - 1.0

so that the error function doesn't exceed 1. Solving for K,

K > 0.002929687499688476

The value of the error function can be decreased as long as it is not less than zero. Thus

K/(100*365.2425) __<__ 0.000006904926745444993

and solving for K

K __<__ 0.2521972656249999

Thus

0.002929687499688476 < K __<__ 0 .2521972656249999

Therefore,

[Y/100] = INT((365*Y + [Y/4] - [Y/100] + [Y/400] + D - K)/(100*365.2425))

where

0.002929687499688476 < K __<__ 0.2521972656249999

=INT((365*Y + [Y/4] - [Y/100] + [Y/400] + D - K)/(400*365.2425))

where

0.002929687515908501 < K __<__ 1

However, once [Y/100] has been determined, [ [Y/100]/4] = [Y/400] can be easily calculated.

365*Y + [Y/4] -[Y/100] + [Y/400] + D

can be converted into

365*Y +[Y/4] + D

by adding our value for [Y/100] and subtracting our value for [Y/400]. Our task is now to find Y given

365*Y +[Y/4] + D

This can be done using the approximation

[(365*Y +[Y/4] + D)/365.25]

=[(365*Y + 0.25*Y - 0.25*Y+[Y/4] + D)/365.25]

=[(365.25*Y - 0.25*Y+[Y/4] + D)/365.25]

=Y + [( [Y/4] - Y/4 + D)/365.25]

Examining the error function

( [Y/4] - Y/4 + D)/365.25

reveals that it has a minimum of 0.000684462696783017 that occurs both at leap year 259 day 1 and non-leap year 299 day 1. The maximum is 1 at leap year 3 day 366. Thus the error function's value is reduced to zero when the greatest integer function is applied to that value if a constant K is first subtracted:

( [Y/4] - Y/4 + D - K)/365.25

where

0 < K __<__ 365.25*0.000684462696783017 = 0.25

365.2425*100 *[Y/100]

from the day count. If variable "I" represents this number of days within a century (assuming a year starting March 1 of the year 0 and the full 100 year intervals were subtracted relative to that date), then

INT(I/365.25)= [I/365.25]

gives the year number except when I is a multiple of 4. When I is a multiple of 4, then the interval represents a time period that includes, as its last day, a leap day. In this case I is exactly divisible by 365.25 (that is, the remainder is zero) but the year value is one less than the quotient. It can be shown that the function:

[I/(365.25 + 1/4000)]= [I/365.25]

provided I is not a multiple of 4 and is less than 365.25*100 and

if I is a multiple of 4 then

[I/365.25] = [I/(365.25 + 1/4000)] + 1

The function [I/(365.25 + 1/4000)] therefore satisfies the requirement.

D = Z - INT(365.25*Y - [Y/100] + [Y/400])

where D is the day number within Y of our Gregorian target date.

Notice that if in the process of calculating a Gregorian date,

365*Y +[Y/4] + D

has been calculated and the year day number D can be calculated by subtracting 365.25*Y.

The number of days in the months prior to the month of our date are now accounted for given the day number since March 1 of the date's year. Writing out the range and domain of the function explicitly:

days in previous months | month |
---|---|

0 | 3 |

31 | 4 |

61 | 5 |

92 | 6 |

122 | 7 |

153 | 8 |

184 | 9 |

214 | 10 |

245 | 11 |

275 | 12 |

306 | 13 |

337 | 14 |

Since, all the months except February are either 30 or 31 days long, one might suspect that a linear approximation can be used and the fractional parts removed to generate a convenient form of the function. One can't be certain that this will work on a particular function before the situation is examined in more detail, but, as will be shown, the function given in the table can be successfully treated this way.

The function will take the form:

FIX(M*X+B)

where

X = day number,

M = the slope of the line,

B= the Y intercept of the line, and

FIX() is the truncation function.

Now since FIX() removes the fraction, the values of MX+B that have the same resulting function, are values from some integer, say Y, up to, but not including, the value Y+1. The range of values for each X can be graphed, but because of the scale, it would be difficult to see precisely how the required line would fit through all the ranges for each function value or whether or not it is even possible to do so. However, it isn't difficult to write a computer program that determines what equations can pass through these intervals. Doing so reveals that the line with maximum slope goes from point (123,7) to (337,14), has slope 0.03271028037383177 and Y intercept = 2.976635514018692. The line with minimum slope goes from (276,12) to (31,4), has a slope = .0326530612244898 and Y intercept = 2.987755102040816. These two lines cross at (194.3333333333375, 9.333333333333469) and I call this the pivot point, since there will be lines that pass within the specified intervals, go through this point, and take on any of the slopes from .0326530612244898 to 0.03271028037383177. Given slope M, the value

9.333333333333469 - M * 194.3333333333375

can be used as the Y intercept. However, there will usually be many other Y intercept values that work as well. For example, a slope of 0.03268167079916079 has a range of Y intercepts from 2.980154491703223 to 2.986276940682814.

This information can be used to look for a function in the form:

(AX + B)\C

where A, B, and C are integers. In particular, small values of C and values of C that are powers of 2 were searched for so that the division could be effected by shifts. Some of the many possible values are displayed in the following table:

C | A | B range (value of upper bound can not be used) |
---|---|---|

153 | 5 | 455.9999999999999 to 456.9999999999999 |

306 | 10 | 911.9999999999999 to 913.9999999999998 |

367 | 12 | 1093 to 1094 |

398 | 13 | 1188 to 1189 |

16384 | 535 | 48948 to 48951 |

32768 | 1070 | 97896 to 97902 |

32768 | 1071 | 97643 to 97825 |

65536 | 2140 | 195792 to 195804 |

65536 | 2141 | 195516 to 195773 |

65536 | 2142 | 195286 to 195650 |

65536 | 2143 | 195163 to 195313 |

The Julian Day Number is converted to the number of days from a base date of March 1 in the year zero. This creates a calendar with January and February as months 13 and 14 rather than months 1 and 2. The purpose of this scheme is to cause any extra day in a leap year to occur at the end of the "year." As will be seen, this simplifies the calculation of the number of leap years from year zero to a particular date and it simplifies the function which relates the number of days in the preceding months to the month number.

Let MOD be the modulo function. Julian year Y is a leap year if Y MOD 4 = 0. In our year starting on March 1, the days in that year span two different years that start on January 1. For example, if February 29 is in year Y for a year beginning January 1, it is in year Y-1 for a year beginning March 1. Similarly, to see if there is an extra day due to a leap year in year Y of a calendar beginning March 1, then our Julian leap year test must be applied to year Y+1.

From Table 2, it can be seen that in order to convert our Julian Day Number to the number of days since March 1 of the year zero in the Julian calendar, 1721117.5 must be subtracted. If day 1 is to be **on** March 1 of the year zero in the Julian, 1721116.5 would be subtracted.

If Z is the number of days since our base year and Y the year of the date to be determined, then

D = Z - 365.25*Y

will be the day number within year Y of our Julian Target date. The number of days accounted for by a span of Y years, although equal to 365*Y+[Y/4], is approximately equal to 365*Y+Y/4 = 365.24*Y since the greatest integer function changes the value of its argument by less than 1. If D is the day number of year Y with values 1 through 365 (or 366 if a leap year), then the task is to find Y given

365*Y+[Y/4] + D days.

Y must then be approximately

INT((365*Y+[Y/4] + D)/365.25)

Examining the error from this approximation:

INT((365*Y+[Y/4] + D)/365.25)
= INT((365*Y+[Y/4] + D)/365.25)

=[(365*Y + 0.25*Y - 0.25*Y+[Y/4] + D)/365.25]

=[(365.25*Y - 0.25*Y+[Y/4] + D)/365.25]

=Y + [( [Y/4] - Y/4 + D)/365.25]

Examining the error function

( [Y/4] - Y/4 + D)/365.25

reveals that it has a minimum of 0.000684462696783017 that occurs both at leap year 259 day 1 and non-leap year 299 day 1. The maximum is 1 at leap year 3 day 366. Thus the error function's value is reduced to zero when the greatest integer function is applied to that value if a constant K is first subtracted:

( [Y/4] - Y/4 + D - K)/365.25

where

0 < K __<__ 365.25*0.000684462696783017 = 0.25

LAST MODIFIED: August 4, 1998