/* juldates.c ********************************************************************************
* juldates.c
*
* This set of Julian routines converts between times and Julian dates, where
* Julian dates can be in any of three possible time systems: Universal time
* (UTC), Atomic time (TAI) and Ephemeris time (ET).
*
* RL_FLT8 Jul_TAIofJD(jd, type)
* RL_FLT8 Jul_JDofTAI(tai, type)
* converts between Julian dates and seconds since J2000 TAI.
* RL_FLT8 Jul_TAIofMJD(mjd, type)
* RL_FLT8 Jul_MJDofTAI(tai, type)
* converts between modified Julian dates and seconds since J2000
* TAI.
*
* Mark R. Showalter, PDS Ring-Moon Systems Node, December 1995
* Revised by MRS 6/98 to conform to RingLib naming conventions.
*******************************************************************************/
#include <math.h>
#include "julian.h"
#include "fortran.h"
/***********************************************************
* Definitions
***********************************************************/
#define MJD_OF_J2000_NOON 51544.5 /* Modified Julian Date of J2000 noon */
#define JD_OF_J2000_NOON 2451545.0 /* Julian Date of J2000 noon */
/***********************************************************
* Prototypes of internal functions
***********************************************************/
static RL_FLT8 ZJul_DUTCfloatofTAI RL_PROTO((RL_FLT8 tai));
static RL_FLT8 ZJul_TAIofDUTCfloat RL_PROTO((RL_FLT8 dfloat));
/*
********************************************************************************
* EXPORTED USER ROUTINES
********************************************************************************
*$ Component_name:
* Jul_TAIofJD (juldates.c)
*$ Abstract:
* Converts a Julian date to a number of seconds relative to J2000 TAI.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* C, PUBLIC
*$ Declarations:
* RL_FLT8 Jul_TAIofJD(jd, type)
* RL_FLT8 jd;
* RL_INT4 type;
*$ Inputs:
* jd Julian date, in one of three possible time systems.
* type type of the Julian date, one of the constants
* JUL_UTC_TYPE (0), JUL_TAI_TYPE (1), or JUL_ET_TYPE (2).
*$ Outputs:
* none
*$ Returns:
* number of seconds since noon J2000 TAI.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a Julian date to a number of seconds relative to
* J2000 TAI. The Julian date may be given in any of three possible time
* systems: Universal time (UTC), Atomic time (TAI), or Ephemeris time
* (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Julian dates slightly
* non-uniform.
*$ External_references:
* Jul_TAIofET()
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, JUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 Jul_TAIofJD(jd, type)
RL_FLT8 jd;
RL_INT4 type;
{
RL_FLT8 tai, et;
switch (type) {
case JUL_TAI_TYPE:
tai = (jd - JD_OF_J2000_NOON) * 86400.;
return tai;
case JUL_ET_TYPE:
et = (jd - JD_OF_J2000_NOON) * 86400.;
return Jul_TAIofET(et);
default:
return ZJul_TAIofDUTCfloat(jd - JD_OF_J2000_NOON);
}
}
/*
********************************************************************************
*$ Component_name:
* Jul_JDofTAI (juldates.c)
*$ Abstract:
* Converts a number of seconds relative to J2000 TAI to a Julian date.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* C, PUBLIC
*$ Declarations:
* RL_FLT8 Jul_JDofTAI(tai, type)
* RL_FLT8 tai;
* RL_INT4 type;
*$ Inputs:
* tai number of seconds since noon J2000 TAI.
* type type of the Julian date, one of the constants
* JUL_UTC_TYPE (0), JUL_TAI_TYPE (1), or JUL_ET_TYPE (2).
*$ Outputs:
* none
*$ Returns:
* jd Julian date, in one of three possible time systems.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a number of seconds relative to J2000 TAI to a
* Julian date. The Julian date is given in any of three possible time
* systems: Universal time (UTC), Atomic time (TAI), or Ephemeris time
* (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Julian dates slightly
* non-uniform.
*$ External_references:
* none
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, JUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 Jul_JDofTAI(tai, type)
RL_FLT8 tai;
RL_INT4 type;
{
RL_FLT8 et;
switch (type) {
case JUL_TAI_TYPE:
return tai/86400. + JD_OF_J2000_NOON;
case JUL_ET_TYPE:
et = Jul_ETofTAI(tai);
return et/86400. + JD_OF_J2000_NOON;
default:
return ZJul_DUTCfloatofTAI(tai) + JD_OF_J2000_NOON;
}
}
/*
********************************************************************************
*$ Component_name:
* Jul_TAIofMJD (juldates.c)
*$ Abstract:
* Converts a Modified Julian date to a number of seconds relative to J2000
* TAI.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* C, PUBLIC
*$ Declarations:
* RL_FLT8 Jul_TAIofMJD(mjd, type)
* RL_FLT8 mjd;
* RL_INT4 type;
*$ Inputs:
* mjd Modified Julian date, in one of three possible time
* systems.
* type type of the Modified Julian date, one of the constants
* JUL_UTC_TYPE (0), JUL_TAI_TYPE (1), or JUL_ET_TYPE (2).
*$ Outputs:
* none
*$ Returns:
* number of seconds since noon J2000 TAI.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a Modified Julian date to a number of seconds
* relative to J2000 TAI. The Julian date may be given in any of three
* possible time systems: Universal time (UTC), Atomic time (TAI), or
* Ephemeris time (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Modified Julian dates slightly
* non-uniform.
*$ External_references:
* Jul_TAIofET()
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, JUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 Jul_TAIofMJD(mjd, type)
RL_FLT8 mjd;
RL_INT4 type;
{
RL_FLT8 tai, et;
switch (type) {
case JUL_TAI_TYPE:
tai = (mjd - MJD_OF_J2000_NOON) * 86400.;
return tai;
case JUL_ET_TYPE:
et = (mjd - MJD_OF_J2000_NOON) * 86400.;
return Jul_TAIofET(et);
default:
return ZJul_TAIofDUTCfloat(mjd - MJD_OF_J2000_NOON);
}
}
/*
********************************************************************************
*$ Component_name:
* Jul_MJDofTAI (juldates.c)
*$ Abstract:
* Converts a number of seconds relative to J2000 TAI to a Modified Julian
* date.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* C, PUBLIC
*$ Declarations:
* RL_FLT8 Jul_MJDofTAI(tai, type)
* RL_FLT8 tai;
* RL_INT4 type;
*$ Inputs:
* tai number of seconds since noon J2000 TAI.
* type type of the Modified Julian date, one of the constants
* JUL_UTC_TYPE (0), JUL_TAI_TYPE (1), or JUL_ET_TYPE (2).
*$ Outputs:
* none
*$ Returns:
* jd Modified Julian date, in one of three possible time
* systems.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a number of seconds relative to J2000 TAI to a
* Julian date. The Julian date is given in any of three possible time
* systems: Universal time (UTC), Atomic time (TAI), or Ephemeris time
* (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Julian dates slightly
* non-uniform.
*$ External_references:
* none
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, JUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 Jul_MJDofTAI(tai, type)
RL_FLT8 tai;
RL_INT4 type;
{
RL_FLT8 et;
switch (type) {
case JUL_TAI_TYPE:
return tai/86400. + MJD_OF_J2000_NOON;
case JUL_ET_TYPE:
et = Jul_ETofTAI(tai);
return et/86400. + MJD_OF_J2000_NOON;
default:
return ZJul_DUTCfloatofTAI(tai) + MJD_OF_J2000_NOON;
}
}
/*
********************************************************************************
* INTERNAL FUNCTIONS
********************************************************************************
* RL_FLT8 ZJul_TAIofDUTCfloat(RL_FLT8 dfloat)
*
* This internal function calculates the number of seconds TAI from the floating-
* point number of days UTC relative to noon J2000.
*
* Input:
* dfloat days relative to J2000 noon UTC.
*
* Return: seconds from J2000 noon TAI.
*******************************************************************************/
static RL_FLT8 ZJul_TAIofDUTCfloat(dfloat)
RL_FLT8 dfloat;
{
RL_FLT8 dfloor, frac, leaps;
RL_INT4 dutc_noon;
dfloor = floor(dfloat);
dutc_noon = (RL_INT4) dfloor;
leaps = Jul_LeapSecs(dutc_noon);
frac = dfloat - dfloor;
if (frac != 0.) frac *= (86400. + Jul_LeapSecs(dutc_noon+1) - leaps);
return 86400.*dutc_noon + leaps + frac;
}
/*
********************************************************************************
* RL_FLT8 ZJul_DUTCfloatofTAI(RL_FLT8 tai)
*
* This internal function calculates the floating-point number of days UTC
* relative to noon J2000 from the number of seconds TAI.
*
* Input:
* tai seconds from J2000 noon TAI.
*
* Return: days relative to J2000 noon UTC.
*******************************************************************************/
static RL_FLT8 ZJul_DUTCfloatofTAI(tai)
RL_FLT8 tai;
{
RL_FLT8 frac, secs;
RL_INT4 dutc;
dutc = Jul_DUTCofTAI(tai, &secs);
secs -= 43200.; /* seconds relative to noon */
if (secs < 0.) {
dutc--;
frac = secs / Jul_DaySecs(dutc) + 1.;
}
else {
frac = secs / Jul_DaySecs(dutc);
}
return dutc + frac;
}
/*
********************************************************************************
* FORTRAN INTERFACE ROUTINES
********************************************************************************
*$ Component_name:
* FJul_TAIofJD (juldates.c)
*$ Abstract:
* Converts a Julian date to a number of seconds relative to J2000 TAI.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* FORTRAN, PUBLIC
*$ Declarations:
* real*8 function FJul_TAIofJD(jd, type)
* real*8 jd
* integer*4 type;
*$ Inputs:
* jd Julian date, in one of three possible time systems.
* type type of the Julian date, one of the constants
* FJUL_UTC_TYPE (0), FJUL_TAI_TYPE (1), or FJUL_ET_TYPE
* (2). These parameters are defined in include file
* "fjulian.inc".
*$ Outputs:
* none
*$ Returns:
* number of seconds since noon J2000 TAI.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a Julian date to a number of seconds relative to
* J2000 TAI. The Julian date may be given in any of three possible time
* systems: Universal time (UTC), Atomic time (TAI), or Ephemeris time
* (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Julian dates slightly
* non-uniform.
*$ External_references:
* Jul_TAIofJD(), FORT_Init()
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, FJUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 FORTRAN_NAME(fjul_taiofjd) (jd, type)
RL_FLT8 *jd;
RL_INT4 *type;
{
FORT_Init();
return Jul_TAIofJD(*jd, *type);
}
/*
********************************************************************************
*$ Component_name:
* FJul_JDofTAI (juldates.c)
*$ Abstract:
* Converts a number of seconds relative to J2000 TAI to a Julian date.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* FORTRAN, PUBLIC
*$ Declarations:
* real*8 function FJul_JDofTAI(tai, type)
* real*8 tai
* integer*4 type
*$ Inputs:
* tai number of seconds since noon J2000 TAI.
* type type of the Julian date, one of the constants
* FJUL_UTC_TYPE (0), FJUL_TAI_TYPE (1), or FJUL_ET_TYPE
* (2). These parameters are defined in include file
* "fjulian.inc".
*$ Outputs:
* none
*$ Returns:
* jd Julian date, in one of three possible time systems.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a number of seconds relative to J2000 TAI to a
* Julian date. The Julian date is given in any of three possible time
* systems: Universal time (UTC), Atomic time (TAI), or Ephemeris time
* (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Julian dates slightly
* non-uniform.
*$ External_references:
* Jul_JDofTAI(), FORT_Init()
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, FJUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 FORTRAN_NAME(fjul_jdoftai) (tai, type)
RL_FLT8 *tai;
RL_INT4 *type;
{
FORT_Init();
return Jul_JDofTAI(*tai, *type);
}
/*
********************************************************************************
*$ Component_name:
* FJul_TAIofMJD (juldates.c)
*$ Abstract:
* Converts a Modified Julian date to a number of seconds relative to J2000
* TAI.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* FORTRAN, PUBLIC
*$ Declarations:
* real*8 function FJul_TAIofMJD(mjd, type)
* real*8 mjd
* integer*4 type
*$ Inputs:
* mjd Modified Julian date, in one of three possible time
* systems.
* type type of the Modified Julian date, one of the constants
* FJUL_UTC_TYPE (0), FJUL_TAI_TYPE (1), or FJUL_ET_TYPE
* (2). These parameters are defined in include file
* "fjulian.inc".
*$ Outputs:
* none
*$ Returns:
* number of seconds since noon J2000 TAI.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a Modified Julian date to a number of seconds
* relative to J2000 TAI. The Julian date may be given in any of three
* possible time systems: Universal time (UTC), Atomic time (TAI), or
* Ephemeris time (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Modified Julian dates slightly
* non-uniform.
*$ External_references:
* Jul_TAIofMJD(), FORT_Init()
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, JUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 FORTRAN_NAME(fjul_taiofmjd) (mjd, type)
RL_FLT8 *mjd;
RL_INT4 *type;
{
FORT_Init();
return Jul_TAIofMJD(*mjd, *type);
}
/*
********************************************************************************
*$ Component_name:
* FJul_MJDofTAI (juldates.c)
*$ Abstract:
* Converts a number of seconds relative to J2000 TAI to a Modified Julian
* date.
*$ Keywords:
* JULIAN, TIME, ATOMIC_TIME, UNIVERSAL_TIME, EPHEMERIS_TIME, JULIAN_DATE
* FORTRAN, PUBLIC
*$ Declarations:
* real*8 function FJul_MJDofTAI(tai, type)
* real*8 tai
* integer*4 type
*$ Inputs:
* tai number of seconds since noon J2000 TAI.
* type type of the Modified Julian date, one of the constants
* FJUL_UTC_TYPE (0), FJUL_TAI_TYPE (1), For JUL_ET_TYPE
* (2). These parameters are defined in include file
* "fjulian.inc".
*$ Outputs:
* none
*$ Returns:
* mjd Modifed Julian date, in one of three possible time
* systems.
*$ Side_effects:
* none
*$ Detailed_description:
* This function converts a number of seconds relative to J2000 TAI to a
* Julian date. The Julian date is given in any of three possible time
* systems: Universal time (UTC), Atomic time (TAI), or Ephemeris time
* (ET).
*
* If the date type is UTC, fractional days are scaled by the number of
* seconds between one UTC noon and the next; since some days have leap
* seconds, this makes the spacing of UTC Julian dates slightly
* non-uniform.
*$ External_references:
* Jul_MJDofTAI(), FORT_Init()
*$ Examples:
* none
*$ Error_handling:
* If the type constant is not one of the allowed values, JUL_UTC_TYPE is
* assumed.
*$ Limitations:
* none
*$ Author_and_institution:
* Mark R. Showalter
* PDS Ring-Moon Systems Node
* NASA/Ames Research Center
*$ Version_and_date:
* 1.0: December 1995
*$ Change_history:
* none
*******************************************************************************/
RL_FLT8 FORTRAN_NAME(fjul_mjdoftai) (tai, type)
RL_FLT8 *tai;
RL_INT4 *type;
{
FORT_Init();
return Jul_MJDofTAI(*tai, *type);
}
/*******************************************************************************
*/