Converting Between Julian Dates and Gregorian Calendar Dates in Fortran (and JavaScript)

By | May 29, 2016
When looking through some of my old papers I found at my father’s house after he died, I found some old Fortran code for converting Gergorian calendar dates to and from Julian dates. I haven’t used Fortran since the 1970s, so the code looked a little strange. Some examples of Julian dates:

Julian Date Equivalent Gregorian Date
2369916.0 July 4, 1776 12:00:00.0 UT
2436911.509722 December 9, 1959 00:14:00.0 UT
2457533.5 May 25, 2016 00:00:00.0 UT

Julian dates are a continuous count of days since Greenwich Mean Noon on January 1, 4713 BCE. January 1, 4713 BCE is also known as -4712 January 1 when used for astronomical calculations. The apparent one year difference is due to there being no year 0—the day after December 31, 1 BCE was January 1, 1 CE. It makes adding and subtracting dates easier.

Greenwich Mean Noon is 12:00 noon UT (Universal Time). UT is a time standard based on Earth’s rotation. It is a modern continuation of Greenwich Mean Time (GMT), i.e., the mean solar time on the Prime Meridian at Greenwich, London, UK. In fact, the expression “Universal Time” is ambiguous when accuracy of better than a few seconds is required, as there are several versions of it, the most commonly used being Coordinated Universal Time (UTC) and UT1. All of these versions of UT, except for UTC, are based on Earth’s rotation relative to distant celestial objects (stars and quasars), but with a scaling factor and other adjustments to make them closer to solar time. UTC, on the other hand, is based on International Atomic Time, with leap seconds added to keep it within 0.9 second of UT1.

Gregorian Calendar Date to Julian Date Formula

Conversion of a Gregorian calendar date to a Julian date for years 1801–2099 CE can be carried out with the following formula (in JavaScript notation). The indentation is a little strange, but that was meant to make it easier to read the formula,

<script>// <![CDATA[
    julianDate =
        367 * year -
        ccTruncate((7 * (year +
            ccTruncate((month + 9) / 12, 0)
        )) / 4, 0)
        +
        ccTruncate((275 * month) / 9, 0)
        + day + 1721013.5 + universalTime / 24
        - 0.5 * ccGetSign(100 * year + month - 190002.5) + 0.5;
// ]]></script>

Where year is in the range 1801–2099, month is in the range 1–12, day is in the range 1–31, and universalTime is the universal time in hours. The last two terms in the formula add up to zero for all dates after 1900 February 28, so these two terms can be omitted for subsequent dates. This formula makes use of the ccGetSign() and ccTruncate() functions described below:

ccGetSign() and ccTruncate() Functions

The ccGetSign() function serves to extract the sign, positive or negative, from a number.

<script>// <![CDATA[
function ccGetSign(number) {
    if (number < 0)
        return -1;
    return 1;
}
// ]]></script>

The ccTruncate() function extracts the integral part of a number. Here’s the JavaScript code for it in case you think it’s useful.

<script>// <![CDATA[
function ccTruncate(number, places) {
    var shift = Math.pow(10, places);
    return ((number * shift) | 0) / shift;
};
// ]]></script>

For the current problem we just need to truncate floating point numbers to make them integers, but this function will work for all kinds of decimal places.

Conversion from a Gregorian Calendar Date to a Julian Date

Here is the Fortran code that takes a year, month, and day in the Gregorian calendar as an input and returns the Julian date. This is valid for any Gregorian calendar date producing a Julian date greater than zero.

    INTEGER FUNCTION JD (YEAR,MONTH,DAY)
C
C   COMPUTES THE JULIAN DATE (JD) GIVEN A GREGORIAN CALENDAR
C   DATE (YEAR,MONTH,DAY).
C
    INTEGER YEAR,MONTH,DAY,I,J,K
C
    I= YEAR
    J= MONTH
    K= DAY
C
    JD= K-32075+1461*(I+4800+(J-14)/12)/4+367*(J-2-(J-14)/12*12)
   2    /12-3*((I+4900+(J-14)/12)/100)/4
C
    RETURN
    END

JavaScript Example

Example using January 1, 1970 (Julian date 2440588):

<script>// <![CDATA[
    var jd, year, month, day, i, j, k;

    year = 1970;
    month = 1;
    day = 1;

    i = year;
    j = month;
    k = day;

    jd = Math.floor(k - 32075 + 1461 * (i + 4800 + (j - 14) / 12) / 4 + 367 * (j - 2 - (j - 14) / 12 * 12) / 12 - 3 * ((i + 4900 + (j - 14) / 12) / 100) / 4);

    document.write("julian date = " + jd);
// ]]></script>

Note: This formula works if JavaScript’s Math.floor() function is applied at the very end of the calculation. When Math.floor() was applied after every division operation, it produced inaccurate results.

Conversion from a Julian Date to a Gregorian Calendar Date

Here is the Fortran code that takes a Julian date as an input and returns the year, month, and day in the Gregorian calendar.

    GDATE (JD, YEAR,MONTH,DAY)
C
C   COMPUTES THE GREGORIAN CALENDAR DATE (YEAR,MONTH,DAY)
C   GIVEN THE JULIAN DATE (JD).
C
    INTEGER JD,YEAR,MONTH,DAY,I,J,K
C
    L= JD+68569
    N= 4*L/146097
    L= L-(146097*N+3)/4
    I= 4000*(L+1)/1461001
    L= L-1461*I/4+31
    J= 80*L/2447
    K= L-2447*J/80
    L= J/11
    J= J+2-12*L
    I= 100*(N-49)+I+L
C
    YEAR= I
    MONTH= J
    DAY= K
C
    RETURN
    END

JavaScript Example

In the example code below, JavaScript’s Math.floor() function is used after each division operation to make sure all the values are integers like they are in Fortran.

Example using Julian date 2440588 (January 1, 1970):

<script>// <![CDATA[
    var jd, year, month, day, l, n, i, j, k;
    jd = 2440588;
    l = jd + 68569;
    n = Math.floor(Math.floor(4 * l) / 146097);
    l = l - Math.floor((146097 * n + 3) / 4);
    i = Math.floor(4000 * (l + 1) / 1461001);
    l = l - Math.floor(1461 * i / 4) + 31;
    j = Math.floor(80 * l / 2447);
    k = l - Math.floor(2447 * j / 80);
    l = Math.floor(j / 11);
    j = j + 2 - 12 * l;
    i = 100 * (n - 49) + i + l;

    year = i;
    month = j;
    day = k;

    document.write("year = " + year + ", month = " + month + ", day = " + day);
// ]]></script>

Leave a Reply