## 2.3 Gregorian date to Julian Day Number - Implementation Examples

### 2.3.0.1 Choices to be made

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?

### 2.3.0.2 Notation

[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)

### 2.3.1 Gregorian Date to Julian Day Number

1. For a Gregorian Date specified as day D (a real number), month M (an integer with January = 1), and year Y (any integer), the Julian Day Number JD can be calculated as follows:

IF M < 3 THEN
M = M + 12
Y=Y-1
END IF
JD = D + (153 * M - 457) \ 5 + 365 * Y + [Y / 4] - [Y / 100] + [Y / 400] + 1721118.5

• The range of years that are supported is only limited by the word size of the implementation.
• Although (153 * M - 457) \ 5 is an elegant expression, an indexed array is usually a faster implementation.
• Some languages only implement the greatest integer function for a real argument.

2. QBASIC Implementation as a subroutine:

SUB jdg (jd AS DOUBLE, y1 AS LONG, m1 AS INTEGER, d AS DOUBLE)
y& = y1 'don't modify year input parameter
m% = m1 'don't modify month input parameter
IF m% < 3 THEN 'months are January or February
m% = m% + 12 'January=13, February=14
y& = y& - 1 'of the previous year
END IF 'months are January or February
jd=d#+(153*m%-457)\5+INT(365.25#*y&)-INT(y&*.01#)+INT(y&*.0025#)+1721118.5#
END SUB

3. In Astronomical Algorithms,1991, page 61, Jean Meeus gives the algorithm (essentially) as

IF M < 3 THEN
M = M + 12
Y = Y - 1
END IF
JD=FIX(365.25(Y+4716))+FIX(30.6001(m+1))+D+2-FIX(Y/100)+FIX(FIX(Y/100)/4)-1524.5

Since 365.25*4716 = 1,722,519.0,
and 30.6001(m+1)) = FIX(30.6001*m - 91.4) + 122,
and FIX(FIX(y/100)/4) = FIX(Y/400),

and since 1,722,519.0 + 122 + 2 - 1524.5 = 1721118.5,
this is equivalent to our derived algorithm provided the years are positive.

• This algorithm is only valid for non-negative Y. It can be made suitable for negative Y by replacing the FIX function with the greatest integer function.
• The constant 4716 was introduced in the process of creating an expression that would allow for the JD to be calculated for negative Julian Dates. It unnecessarily complicates the algorithm for Gregorian dates.
• The constant 30.6001 is used instead of 30.6 because of concern for rounding errors. The previous derivation of the constant 30.6 shows that this is an unwarranted concern.
• There is nothing gained by using
FIX(FIX(Y/100)/4) rather than FIX(Y/400)
or equivalently,
A=FIX(Y/100)
and using -A+FIX(A/4) for the value of - [Y / 100] + [Y / 400]
unless A/4 is performed using a shift operation.

4. For dates in the Gregorian calendar at noon, The Explanatory Supplement to the Astronomical Almanac,1992, page 604, gives the value for the Julian Day Number for a Gregorian Date after November 23, -4713 as:

JD=(1461*(Y+4800+(M-14)\12))\4+(367*(M-2-12*((M-14)\12)))\12-(3*((Y+4900+(M-14)\12)\100))\4+D-32075

Here the expression:
(M - 14)\12
is used to implement the conditional change of Y and M that can be more clearly expressed as:

IF M < 3 THEN
M = M + 12
Y = Y - 1
END IF

With this change in the values of M and Y,
JD=(1461*(Y+4800))\4+(367*(M-2))\12-(3*((Y+4900)\100))\4+D-32075

Assume Y is non-negative (or use INT instead of FIX in the following argument). The following identities can be shown to hold:

1. (1461*(Y+4800))\4 = FIX(365.25*Y) + 1753200
2. 367*(M-2))\12 = FIX( 30.583333333*M - 91.166666666) + 30
3. -(3*((Y+4900)\100))\4 = -FIX(Y/100) + FIX(Y/4) - 36

therefore the formula can be rewritten as

JD = FIX(365.25*Y) + FIX( 30.583333333*M - 91.166666666) - FIX(Y/100) + FIX(Y/4) + D - 32075 - 36 + 30 + 1753200

= FIX(365.25*Y) + FIX( 30.583333333*M - 91.166666666) - FIX(Y/100) + FIX(Y/4) + D + 1721119

which was shown in the development section to be the JD provided that the date specification is for noon and the years are non-negative.

• The algorithm is not valid for Gregorian years less than -4800.
• The reference time is for noon of the specified day. Thus the JD is from noon of the specified day until noon of the following day.
• The constants 4800 and 4900 were introduced so that the FIX function produces the correct result for negative Gregorian dates as small as -4800.
• If INT is available or the years are non-negative,
using INT(365.25*Y) or 365*Y + INT(Y/4) in the algorithm is a better choice than
(1461*(Y + 4800))\4
since the range of years is greater.
• If INT is available or the years are non-negative,
-INT(Y/100) + INT(Y/4) is a better choice than -(3*((Y+4900)\100))\4

### 2.3.2 Julian date to Julian Day Number Implementation Examples

1. For a Julian Date specified as day D (a real number), month M (an integer with January = 1), and year Y (any integer), the Julian Day Number JD can be calculated as follows:
IF M < 3 THEN
M = M + 12
Y=Y-1
END IF
JD = D + (153 * M - 457) \ 5 + 365 * Y + [Y / 4] + 1721116.5

• The range of years that are supported is only limited by the word size of the implementation.
• Although (153 * M - 457) \ 5 is an elegant expression, an indexed array is usually a faster implementation.
• Some languages only implement the greatest integer function for a real argument.

2. QBASIC Implementation as a subroutine:

SUB jdj (jd AS DOUBLE, y1 AS LONG, m1 AS INTEGER, d AS DOUBLE)
'***WARNING**** Input Date is Julian, NOT Gregorian
y& = y1 'don't modify year input parameter
m% = m1 'don't modify month input parameter
IF m% < 3 THEN 'months are January or February
m% = m% + 12 'January=13, February=14
y& = y& - 1 'of the previous year
END IF 'months are January or February
jd=d#+(153*m%-457)\5+INT(365.25#*y&)+1721116.5#
END SUB

3. In Astronomical Algorithms,1991, page 61, Jean Meeus gives the algorithm for a Julian Day number from a Julian Date (essentially) as

IF M < 3 THEN
M = M + 12
Y = Y - 1
END IF
JD = FIX(365.25(Y + 4716)) + FIX(30.6001(M + 1)) + D - 1524.5

Since 365.25*4716 = 1,722,519.0,
and 30.6001(M + 1)) = FIX(30.6001*M - 91.4) + 122,

and since 1,722,519.0 + 122 -1524.5 = 1721116.5,
this is equivalent to our derived algorithm provided the years are not less than -4716. This is assured if the JD is non-negative since JD = 0.0 occurred at noon on January 1, -4712 in the Julian Calendar.