JD (Julian Day) Number For Any Julian or Gregorian Date
And Optional Time and Delta T
Date:   ±Y  M  D Time UT:   H M S ΔT:   ± H M S
Calendar Input Mode:    Julian              Gregorian 
J 2018      May
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
G 2018      May
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
This program uses a cookie to remember the interface settings between calls.

 DATE ISOymd  = 20180521 = 2018 May 21 - Monday (Gregorian)

 Time  UT HMS =  00 00 00.000 = 0 day = UTFrac
 Delta T ±HMS = +00 00 00.000 = 0 day = dTFrac

 JD12 = 2458260 = JD For 12h (midpoint of date) = Standard JD for date
 JD00 = 2458259.5 = (JD12 - 0.5) = JD for 00h (beginning of date)
   JD = 2458259.5 = (JD00 + UTFrac + dTFrac) = Full Astronomical JD

 J2000.0 = 2000 Jan 01 at 12h TDB
       T = 0.18383299110198 Julian centuries reckoned from J2000.0
       t = 0.01838329911019 Julian millennia reckoned from J2000.0

 Gregorian Calendar Date = Julian Date + 13 days 

 Note that the corresponding days of the week are the same on both calendars
 regardless of the number of days difference between them.

The JD number is the single, most important number used for calendrical computations and computing it will usually be the first step in numerous calculations.  It serves as a unique calendrical serial number corresponding to a given date.

The following pseudo-code algorithms can be used as a guide to developing such a general-purpose JD number function.

A typical call to such a JD number function might be symbolized as:

 JD = JD_For_ISOymd (ISOymd, CalMode)

This is the JD number to use when only working with full calendar dates and the time of day is not an issue.  For example, when computing the number of days until next spring, we generally don't consider the time of day in the calculation, we just think of it in terms of whole days, such as 145 days or 85 days, etc.

Algorithm 1 - The simplest case:

Compute the simple Julian Day number (JD) for any given integer-encoded date and calendar mode (ISOymd, CalMode) without regard to the time of day.  The numerical value of this JD number will always equate to a non-negative integer value.

 if (ISOymd < 0) then YearSignVal = -1 else YearSignVal = 1

 u = abs(ISOymd)
 w = floor(u / 10000)

 y = YearSignVal * w
 m = floor((u - 10000*w) / 100)
 d = u - 10000*w - 100*m

 if (y < 0) then w = y+1 else w=y

 a = floor((14-m) / 12)
 b = w - a
 c = floor(b/100)

 JD = floor(30.6001*(12*a + m + 1))
    + floor(365.25*(b + 4716)) - 1524
    + CalMode*(floor(c/4) - c + 2) + d

Although in this simplest case, the JD number may always equate to an integer value, it is recommended that it be assigned to a double precision floating point variable for use in subsequent computations.

The Day of the Week (DoW)

Once we compute the JD number for a given date, one of the first things we can use it for is to determine the day of the week on which the given date falls (Sun, Mon, Tue, etc.).  To do this we simply assign each day of the week (DoW) a sequential index number from 0 to 6, where 0=Sun, 1=Mon, 2=Tue, etc., then we can derive the DoW value from the simple JD number by a simple algorithm.

Mathematically, both the Julian and Gregorians calendar system origins (JD=0), were Mondays in both cases, by definition.  This leads to the following simple algorithm, applicable to either calendar system, which allows us to determine the day of the week from the simple JD number.

Algorithm 1a:

Determine the DoW index from the simple JD number defined above.  The general JD argument used here is always an integer value.

 DoW = (JD + 1) mod 7
The DoW indices are:  0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri, and 6=Sat

The JD number may not always be an integer value.  Sometimes it will be a fractional value.  If you want to extract the corresponding day of the week (DoW) from any JD number in general, integer or fractional, then the following algorithm may be used in the general case.

Algorithm 1b:

Determine the DoW index from any general JD number.  The general JD argument used here can be an integer or fractional value and is NOT restricted only to integers. This algorithm can be used in place of Algorithm 1a, but not vice versa.

 DoW = (floor(JD + 0.5) + 1) mod 7
The DoW indices are:  0=Sun, 1=Mon, 2=Tue, 3=Wed, 4=Thu, 5=Fri, and 6=Sat

This is all we need to begin.  All we need to know is the day of the week on which a given month begins and the number of days in that month to construct a complete calendar according to some simple rules.

Taking Into Account The Time of Day

When used for astronomy, or whenever the time of day becomes a factor in the computation, then the standard integer JD value actually refers to the JD number at the moment of 12h (noon, midpoint) of the civil calendar date.  This is because civil calendar dates are reckoned from midnight-to-midnight while astronomical dates are reckoned from noon-to-noon.  As a result, the civil calendar date is 1/2 (0.5) day ahead of the same corresponding astronomical calendar date. 

What we need to do to use calendar dates for astronomical computations, is to convert the simple calendrical JD number into the corresponding astronomical JD number and then use that value in the subsequent computations.  To accomplish this, simply subtract 0.5 from the simple calendrical JD number for the date.

For 1949 May 20, Gregorian (ISOymd=19490520, CalMode=1)
JD = 2433057
Since this value refers to the JD for noon of that calendar date, to obtain the value of the JD for 00h,
we subtract 0.5 from it, which gives
(2433057 - 0.5) = 2433056.5 = Standard astronomical JD number for 00h of 1949 May 20.

Once we know the JD number value for 00h on the date, we can then proceed to determine the general JD value for any specific time within the day by adding the fraction (UTFrac) of a day corresponding to the time and derived from the given time elements (hh,mm,ss).

 hh = Hours
 mm = Minutes
 ss = Seconds
Examples of some (UTFrac) values:
 hh:mm:ss = UTFrac
 03:00:00 = 0.125 of day since 00h
 06:00:00 = 0.25
 09:00:00 = 0.375
 09:18:54 = 0.388125
 12:00:00 = 0.5
 15:00:00 = 0.625
 17:21:45 = 0.7234375
 18:00:00 = 0.75
 21:00:00 = 0.875
 21:12:36 = 0.88375
 etc. ...
The (UTFrac) values in the examples above were computed from:

Algorithm 1c

From the time elements, compute the corresponding fraction of a day since 00h.  This fraction will always equate to a positive value between 0 and 1.
 UTFrac = (3600*hh + 60*mm + ss) / 86400

For more precise astronomical work, we may need to apply a time correction called Delta T.  Strictly speaking, the actual time used for astronomical computations is sometimes called dynamical time (TD) and is the sum of the universal time (UT) and the ΔT correction, which may be negative or positive, depending on circumstances.

 TD = UT + ΔT 

When we ignore the ΔT correction (equate it to zero), then Universal Time (UT) and Dynamical Time (TD) are treated as equivalent.  Since UT and TD are often very close (within a minute or two), in many cases we can ignore it without consequence.  For example, if we wanted to compute the apparent phase of one of the planets as viewed from Earth, the ΔT correction could be ignored and so could the light-time.

The ΔT correction is mostly used for finer computations, when we need higher accuracy for things like certain eclipses or occultations, and seconds may become very important to our observations.  It is also helpful in historical astronomy where it is used to approximate the direction of the prime meridian with respect to the sun in ancient times so we can better understand ancient observations.

The ΔT correction cannot be exactly computed in advance, but only approximated based on past observations, trends, interpolations and extrpolations.

Algorithm 1d

From the ΔT time elements, we compute the corresponding fraction of a day in the same manner as with the time of day.  In this case the corresponding time fraction may be negative or positive.
(dTSignVal = -1 = Negative  or  dTSignVal = 1 = Positive)
 dTFrac = dTSignVal * (3600*dThh + 60*dTmm + dTss) / 86400

We add the (UTFrac) value to the JD value at 00h to obtain the precise general JD number for the given time of day.

 JD00 = JD_For_ISOymd(ISOymd, CalMode) - 0.5

 UTFrac = (3600*hh + 60*mm + ss) / 86400

 JD = JD00 + UTFrac

Or, eliminating the separate (JD00) and (UTFrac) values, the general JD can found more directly from:

 JD = JD_For_ISOymd(ISOymd, CalMode) - 0.5 + (3600*hh + 60*mm + ss) / 86400

© Jay Tanner - PHP Science Labs - 2018 - v3.1