The following decisions have to be made regarding any implementation:

- Are dates specified in the Gregorian or Julian Calendar?
- What range of dates are to be supported?
- What number word size will be used?
- Is the greatest integer function available or is only the truncation function?
- Is real arithmetic available and required?
- Is conditional execution such as "IF/THEN" supported?

**[x]** = the greatest integer that does not exceed x.
For example, [-1.5]=-2. This is sometimes called the floor function (for
example in C/C++).

**INT(x)** = [x] NOTE: some computer languages have a different
definition.

**FIX(x)** = the number x without its fraction. For example, FIX(-1.5)=-1

**x\y** = FIX(x/y)

- The following sequence calculates Gregorian year Y, month M, and day D from Julian Day Number JD. It uses real arithmetic.

Z = INT(JD - 1721118.5)

R = JD - 1721118.5 - Z

G = Z - .25

A = INT(G / 36524.25)

B = A - INT(A / 4)

year = INT((B+G) / 365.25)

C = B + Z - INT(365.25 * year)

month = FIX((5 * C + 456) / 153)

day = C - FIX((153 * month - 457) / 5) + R

IF month > 12 THEN

year = year + 1

month = month - 12

END IF

COMMENTS:

- The range of years that are supported is only limited by the word size of the implementation.
- Although FIX((5*C + 456)/ 153) and FIX((153*M-457)/5) are elegant expressions, the use of indexed arrays are usually a faster implementation.
- Some languages only implement, within the language proper, the greatest integer function for a real argument. One can, of course, always create this function as part of the program itself.

2. The following sequence calculates Gregorian year Y, month M, and day D from Julian Day Number JD. It uses integer arithmetic except for the values of JD, R, and Day since the Julian Day Number may be fractional.

Z = INT(JD - 1721118.5)

R = JD - 1721118.5 - Z

H = 100*Z - 25

A = INT(H / 3652425)

B = A - INT(A / 4)

year = INT((100*B+H) / 36525)

C = B + Z - 365 * year - INT( year/4)

month = FIX((5 * C + 456) / 153)

day = C - FIX((153 * month - 457) / 5) + R

IF month > 12 THEN

year = year + 1

month = month - 12

END IF

COMMENTS:

- The range of years that are supported is only limited by the word size of the implementation.
- The greatest integer function
can be replaced by integer division if JD
__>__March 1 of the year zero. - Although FIX((5*C + 456)/ 153) and FIX((153*M-457)/5) are elegant expressions, the use of indexed arrays are usually a faster implementation.
- Some languages only implement the greatest integer function for a real argument.

3. The following sequence calculates Gregorian year Y, month M, and day D from Julian Day Number JD. It uses integer arithmetic except for the values of JD, R, and Day since the Julian Day Number may be fractional. It uses integer division and the shift right operator to effect integer division by powers of 2.

****WARNING*** Only valid for dates greater than or equal to 1721118.25 (April 28.75 of the year zero).

Z = INT(JD - 1721118.5)

R = JD - 1721118.5 - Z

H = 100*Z - 25

A = H \ 3652425

B = A - SHIFTRIGHT(A,2)

year = (100*B+H) \ 36525

C = B + Z - 365 * year - SHIFTRIGHT( year,2)

month = SHIFTRIGHT((535*C + 48950),14)

day = C - SHIFTRIGHT( (979*M-2918),5) + R

IF month > 12 THEN

year = year + 1

month = month - 12

END IF

COMMENTS:

- Only valid for dates greater than or equal to 1721118.25 (April 28.75 of the year zero).
- Although SHIFTRIGHT((535*C + 48950),14) and SHIFTRIGHT( (979*M-2918),5) are elegant expressions, the use of indexed arrays are usually a faster implementation.

4. QBASIC Implementation as a subroutine - using real arithmetic:

Note: & indicates 32-bit (long) integer and # indicates double precision real

SUB jdtog1 (jd AS DOUBLE, year AS LONG, month AS
INTEGER, day AS DOUBLE)

'INPUT: jd = Julian Day Number

'OUTPUT: Gregorian year, month, and day

Z& = INT(jd - 1721118.5#) 'Day 1 is on March 1 of the year 0

R# = jd - 1721118.5# - Z& 'the fractional part of the day

G# = Z& - 0.25#

A& = INT(G# / 36524.25#) 'whole centuries

B& = A& - INT(A& / 4#) 'Julian days in whole centuries - 0.25

year = INT((G#+B&) / 365.25#)

C& = Z& +B& - INT(365.25 * year) 'days in the year

month = (5 * C& + 456) \ 153

day = C& - ((153 * month - 457) \ 5) + R#

IF month > 12 THEN 'convert to year that starts January 1

year = year + 1

month = month - 12

END IF 'convert to year that starts January 1

END SUB

5. QBASIC Implementation as a subroutine - Integer arithmetic version:

SUB jdtog2 (JD AS DOUBLE, year AS LONG, month AS
INTEGER, day AS DOUBLE)

'***WARNING*** ONLY VALID IF JD __>__ 1721118.25 (February 28.75 of year
zero)

'INPUT: jd = Julian Day Number

'OUTPUT: Gregorian year, month, and day

Z& = INT(JD - 1721118.5) 'Day 1 is on March 1 of the year 0

R# = JD - 1721118.5 - Z& 'the fractional part of the day

H& = 100*Z& - 25

A& = H&\3652425 'whole centuries

B& = A& - A&\4 'adjustment to find the Julian days in whole
centuries

year = (100*B&+H&) \ 36525

C& = B& + Z& - 365 * year - year\4 'days in the year

month = (5 * C& + 456) \ 153

day = C& - (153 * month - 457) \ 5 + R#

IF month > 12 THEN 'convert to year that starts January 1

year = year + 1

month = month - 12

END IF 'convert to year that starts January 1

END SUB

- In
*Astronomical Algorithms*, 1991, page 63, Jean Meeus (essentially) gives the following algorithm. This can be shown to be an instance of our derived algorithm provided the Julian Day numbers is greater than or equal to 1867215.75, that is, for dates from February 29.25, 400 in the proleptic Gregorian calendar.

Z = FIX(JD +0.5)

R = JD + 0.5 - Z

G = FIX((Z - 1867216.25)/36524.25)

A = Z + 1 + G - FIX(G/4)

B = A + 1524

C = FIX((B - 122.1)/365.25)

D = FIX(365.25*C)

E = FIX((B - D)/30.6001)

Day of month = B - D - FIX(30.6001*E) + R

If E<14 then >

Month = E - 1

Year = C - 4716

else

Month = E - 13

Year = C - 4715

end if

__COMMENTS__:

- This algorithm is only valid for Julian Day numbers greater than or equal to 1867216.25, that is, dates from February 29.75, 400 in the proleptic Gregorian calendar. Note that Meeus states that his algorithm is valid for all non-negative Julian Day numbers but, in fact, his algorithm switches to another form that finds the Julian Date rather than the Gregorian date if the Julian Day Number represents a date before the Gregorian Reform.
- If FIX is replaced with the greatest integer function, the algorithm is valid for all Julian Day Numbers within the range of the word size.
- Meeus states that the 30.6001 in the algorithm can't be replaced by 30.6. An algorithm could be developed that uses a slope of 1/30.6 = 0.03267973856209151 by using a linear function with a Y intercept within the range of 2.980392156862745 to 2.986928104575163.

7.
For dates in the Gregorian calendar at noon, *The
Explanatory Supplement to the Astronomical Almanac*,1992, page 604, gives an
algorithm by Fliegel and Van Flandern that calculates dates after November 23,
-4713, given an integral Julian Day Number. This algorithm can
be shown to be an instance of the general form described in the algorithm development section.

L = JD + 68569

N = FIX((4*L)/146097)

L = L - FIX((146097 * N + 3)/4)

I = FIX(4000 *(L + 1)/1461001)

L = L - FIX((1461*I)/4) + 31

J = FIX((80*L)/2447)

D = L - FIX((2447*J)/80)

L=FIX(J/11)

M = J + 2 - 12*L

Y = 100*(N-49) + I + L

COMMENTS:

- The algorithm is not valid for dates before November 23, -4713 (negative JD numbers).
- The algorithm could be easily modified to handle Julian Day Numbers with a non-zero fractional part. The other algorithms in this section show how this can be done.
- The algorithm is designed so that it can be directly implemented using integer arithmetic and the usual integer division.
- This algorithm uses the alternative method of determining the year given the number of whole centuries as was described in section 3.1.2.5.

- The following sequence calculates Julian year Y, month M, and day D from Julian Day Number JD. It uses real arithmetic.

Z = INT(JD - 1721116.5)

R = JD - 1721116.5 - Z

year = INT((Z - 0.25) / 365.25)

C = Z - INT(365.25 * year)

month = FIX((5 * C + 456) / 153)

day = C - FIX((153 * month - 457) / 5) + R

IF month > 12 THEN

year = year + 1

month = month - 12

END IF

COMMENTS:

- The range of years that are supported is only limited by the word size of the implementation.
- Although FIX((5*C + 456)/ 153) and FIX((153*M - 457)/5) are elegant expressions, the use of indexed arrays are usually a faster implementation.
- Some languages only implement, within the language proper, the greatest integer function for a real argument. One can, of course, always create this function as part of the program itself.

2. The following sequence calculates Julian year Y, month M, and day D from Julian Day Number JD. It uses integer arithmetic except for the values of JD, R, and Day since the Julian Day Number may be fractional.

Z = INT(JD - 1721116.5)

R = JD - 1721116.5 - Z

year = INT((100*Z - 25) / 36525)

C = Z - 365 * year - INT( year/4)

month = FIX((5 * C + 456) / 153)

day = C - FIX((153 * month - 457) / 5) + R

IF month > 12 THEN

year = year + 1

month = month - 12

END IF

COMMENTS:

- The range of years that are supported is only limited by the word size of the implementation.
- The greatest integer
function can be replaced by integer division if JD
__>__April 29 of the year zero. - Although FIX((5*C + 456)/ 153) and FIX((153*M - 457)/5) are elegant expressions, the use of indexed arrays are usually a faster implementation.
- Some languages only implement the greatest integer function for a real argument.

3. The following sequence calculates Julian year Y, month M, and day D from Julian Day Number JD. It uses integer arithmetic except for the values of JD, R, and Day since the Julian Day Number may be fractional. It uses integer division and the shift right operator to effect integer division by powers of 2.

****WARNING*** Only valid for dates greater than or equal to 1721116.25 (February 28.75 of the year zero).

Z = INT(JD - 1721116.5)

R = JD - 1721116.5 - Z

year = FIX((100*Z - 25)) / 36525)

C = Z - 365 * year - SHIFTRIGHT( year,2)

month = SHIFTRIGHT((535*C + 48950),14)

day = C - SHIFTRIGHT( (979*M-2918),5) + R

IF month > 12 THEN

year = year + 1

month = month - 12

END IF

COMMENTS:

- Only valid for dates greater than or equal to 1721116.25 (February 28.75 of the year zero).
- Although SHIFTRIGHT((535*C + 48950),14) and SHIFTRIGHT( (979*M-2918),5) are elegant expressions, the use of indexed arrays are usually a faster implementation.

4. QBASIC Implementation as a subroutine - using real arithmetic:

Note: & indicates 32-bit (long) integer and # indicates double precision real

SUB jdtoj1 (jd AS DOUBLE, year AS LONG, month AS
INTEGER, day AS DOUBLE)

'INPUT: jd = Julian Day Number

'OUTPUT: Julian year, month, and day

Z& = INT(jd - 1721116.5#) 'Day 1 is on March 1 of the year 0

R# = jd - 1721116.5# - Z& 'the fractional part of the day

year = INT((Z& - 0.25#) / 365.25#)

C& = Z& - INT(365.25 * year) 'days in the year

month = (5 * C& + 456) \ 153

day = C& - ((153 * month - 457) \ 5) + R#

IF month > 12 THEN 'convert to year that starts January 1

year = year + 1

month = month - 12

END IF 'convert to year that starts January 1

END SUB

5. QBASIC Implementation as a subroutine - Integer arithmetic version:

SUB jdtoj2 (JD AS DOUBLE, year AS LONG, month AS
INTEGER, day AS DOUBLE)

'***WARNING*** ONLY VALID IF JD __>__ 1721116.5 (April 29 of day zero or
greater)

'INPUT: jd = Julian Day Number

'OUTPUT: Julian year, month, and day

Z& = INT(JD - 1721116.5) 'Day 1 is on March 1 of the year 0

R# = JD - 1721116.5 - Z& 'the fractional part of the day

year = (100*Z& - 25) \ 36525

C& = Z& - 365 * year - year\4 'days in the year

month = (5 * C& + 456) \ 153

day = C& - (153 * month - 457) \ 5 + R#

IF month > 12 THEN 'convert to year that starts January 1

year = year + 1

month = month - 12

END IF 'convert to year that starts January 1

END SUB

- In
*Astronomical Algorithms*, 1991, page 63, Jean Meeus (essentially) gives the following algorithm. This can be shown to be an instance of the previously derived algorithm provided the Julian Day numbers is greater than or equal to 1867215.75, that is, for dates from February 29.25, 400 in the proleptic Gregorian calendar.

Z = FIX(JD +0.5)

R = JD + 0.5 - Z

B = Z + 1524

C = FIX((B - 122.1)/365.25)

D = FIX(365.25*C)

E = FIX((B - D)/30.6001)

Day of month = B - D - FIX(30.6001*E) + R

If E<14 then >

Month = E - 1

Year = C - 4716

else

Month = E - 13

Year = C - 4715

end if

__COMMENTS__:

- This algorithm is only valid for Julian Day numbers greater than or equal to -0.5, that is, dates from noon of January 1, -4712 in the proleptic Julian calendar. Note that Meeus states that his algorithm is valid for all non-negative Julian Day numbers but that his algorithm switches to another form that finds the Julian Date rather than the Gregorian date if the Julian Day Number represents a date before the Gregorian Reform.
- If FIX is replaced with the greatest integer function, the algorithm is valid for all Julian Day Numbers within the range of the word size.
- Meeus states that the 30.6001 in the algorithm can't be replaced by 30.6. An algorithm could be developed that uses a slope of 1/30.6 = 0.03267973856209151 by using a linear function with a Y intercept within the range of 2.980392156862745 to 2.986928104575163.

LAST MODIFIED: September 30, 2007