3.1.1 Julian Day Number to Gregorian date - Algorithm Development

The basic strategy is to:
  1. Convert the Julian Day Number to the number of days from some base date.
  2. Determine the number of years from the base date.
  3. Calculate the number of remaining days once the years are accounted for.
  4. Determine the month number represented by the remaining days.
  5. Calculate the number of remaining days once the months are accounted for.

3.1.1.1 Choosing a Base Date

Algorithm development begins by choosing a base date that our day count will be relative to instead of the less convenient Julian Day Number 0. Since conversion will be to a Gregorian date, this base date will be in the Gregorian year zero.

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.

3.1.1.2 Determining the Year

With the number of days now relative to our base of March 1 of the year 0, the number of full years within the given time span in days is determined. Given year Y, the number of days to account for before the 1st day of that year depends upon the way leap years are calculated. For a Gregorian date, the number of days accounted for by the full years is 365*Y+[Y/4] -[Y/100]+[Y/400] where [x] is the greatest integer function. Here the extra leap year days are added because the date for a calendar beginning March 1 places February 29 in the preceding year.

3.1.1.2.1 Average days per year approximation

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.

3.1.1.2.2 Average days per century approximation

The number of full centuries from the base date to the given date will now be determined.

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

3.1.1.2.3 Days per 400 years approximation

One could similarly evaluate [Y/400] using

=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.

3.1.1.2.4 Application of century and 400 year approximations to determine the year

Since an appropriate constant K can be chosen to make our century and 400 year approximations exactly correct, the day count of

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

3.1.1.2.5 Alternative application of the century to determine the year

Once the number of full centuries have been determined, this number can be used to convert the day count to an interval less than a century and this interval will not require accounting for the troublesome century leap years. In other words subtracting

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.

3.1.1.3 Determining the Day of the Year

If Z is the number of days since our base year and Y the year of the date to be determined, then in the Gregorian Calendar, there will be 365.25*Y - [Y/100] + [Y/400] days up to January 1 of year Y and

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.

3.1.1.4 Determining the Month

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 monthsmonth
0 3
31 4
61 5
92 6
1227
1538
1849
21410
24511
27512
30613
33714

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:

CAB range (value of upper bound can not be used)
1535455.9999999999999 to 456.9999999999999
30610911.9999999999999 to 913.9999999999998
367121093 to 1094
398131188 to 1189
1638453548948 to 48951
32768107097896 to 97902
32768107197643 to 97825
655362140195792 to 195804
655362141195516 to 195773
655362142195286 to 195650
655362143195163 to 195313

3.1.1.5 Determining the Day

Once the month number has been identified, the remaining days can be calculated by subtracting the number of days in the prior months. There are many ways to calculate the function which converts month number to days in prior months. This function was examined as part of algorithm development for converting from a Gregorian or Julian Date to the corresponding Julian Day number and will not be reproduced here.

3.1.2 Julian Day Number to Julian Date - Algorithm Development

3.1.2.1 Choosing a Base Date

Algorithm development begins by choosing a base date that our day count will be relative to instead of the less convenient Julian Day Number 0. Since conversion will be to a Julian date, this base date will be the Julian year zero.

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.

3.1.2.2 Determining the Year

With the number of days now relative to our base of March 1 of the year 0, the number of full years within the given time span in days is determined. Given year Y, the number of days to account for is 365*Y+[Y/4] = [365.25*Y] where [x] is the greatest integer function. Here the extra leap year days are added because the date for a calendar beginning March 1 places February 29 in the preceding year.

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

3.1.2.3 Determining the Month and Day

Once the year has been determined, the procedure for finding the month and day is exactly the same as that described in the previous section for converting a Julian Day Number to a Gregorian date.

AESIR RESEARCH HOME PAGE

LAST MODIFIED: August 4, 1998