double palDat ( double dju ) { int iy; int im; int id; int status; double fd; double deltat; eraJd2cal( PAL__MJD0, dju, &iy, &im, &id, &fd ); status = eraDat( iy, im, id, fd, &deltat ); return deltat; }
int eraUtcut1(double utc1, double utc2, double dut1, double *ut11, double *ut12) /* ** - - - - - - - - - - ** e r a U t c u t 1 ** - - - - - - - - - - ** ** Time scale transformation: Coordinated Universal Time, UTC, to ** Universal Time, UT1. ** ** Given: ** utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-4) ** dut1 double Delta UT1 = UT1-UTC in seconds (Note 5) ** ** Returned: ** ut11,ut12 double UT1 as a 2-part Julian Date (Note 6) ** ** Returned (function value): ** int status: +1 = dubious year (Note 7) ** 0 = OK ** -1 = unacceptable date ** ** Notes: ** ** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any ** convenient way between the two arguments, for example where utc1 ** is the Julian Day Number and utc2 is the fraction of a day. ** ** 2) JD cannot unambiguously represent UTC during a leap second unless ** special measures are taken. The convention in the present ** function is that the JD day represents UTC days whether the ** length is 86399, 86400 or 86401 SI seconds. ** ** 3) The warning status "dubious year" flags UTCs that predate the ** introduction of the time scale and that are too far in the future ** to be trusted. See eraDat for further details. ** ** 4) The function eraDtf2d converts from calendar date and time of ** day into 2-part Julian Date, and in the case of UTC implements ** the leap-second-ambiguity convention described above. ** ** 5) Delta UT1 can be obtained from tabulations provided by the ** International Earth Rotation and Reference Systems Service. It ** It is the caller's responsibility to supply a DUT argument ** containing the UT1-UTC value that matches the given UTC. ** ** 6) The returned ut11,ut12 are such that their sum is the UT1 Julian ** Date. ** ** 7) The warning status "dubious year" flags UTCs that predate the ** introduction of the time scale and that are too far in the future ** to be trusted. See eraDat for further details. ** ** References: ** ** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), ** IERS Technical Note No. 32, BKG (2004) ** ** Explanatory Supplement to the Astronomical Almanac, ** P. Kenneth Seidelmann (ed), University Science Books (1992) ** ** Called: ** eraJd2cal JD to Gregorian calendar ** eraDat delta(AT) = TAI-UTC ** eraUtctai UTC to TAI ** eraTaiut1 TAI to UT1 ** ** Copyright (C) 2013, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { int iy, im, id, js, jw; double w, dat, dta, tai1, tai2; /* Look up TAI-UTC. */ if ( eraJd2cal(utc1, utc2, &iy, &im, &id, &w) ) return -1; js = eraDat ( iy, im, id, 0.0, &dat); if ( js < 0 ) return -1; /* Form UT1-TAI. */ dta = dut1 - dat; /* UTC to TAI to UT1. */ jw = eraUtctai(utc1, utc2, &tai1, &tai2); if ( jw < 0 ) { return -1; } else if ( jw > 0 ) { js = jw; } if ( eraTaiut1(tai1, tai2, dta, ut11, ut12) ) return -1; /* Status. */ return js; }
int eraUtctai(double utc1, double utc2, double *tai1, double *tai2) /* ** - - - - - - - - - - ** e r a U t c t a i ** - - - - - - - - - - ** ** Time scale transformation: Coordinated Universal Time, UTC, to ** International Atomic Time, TAI. ** ** Given: ** utc1,utc2 double UTC as a 2-part quasi Julian Date (Notes 1-4) ** ** Returned: ** tai1,tai2 double TAI as a 2-part Julian Date (Note 5) ** ** Returned (function value): ** int status: +1 = dubious year (Note 3) ** 0 = OK ** -1 = unacceptable date ** ** Notes: ** ** 1) utc1+utc2 is quasi Julian Date (see Note 2), apportioned in any ** convenient way between the two arguments, for example where utc1 ** is the Julian Day Number and utc2 is the fraction of a day. ** ** 2) JD cannot unambiguously represent UTC during a leap second unless ** special measures are taken. The convention in the present ** function is that the JD day represents UTC days whether the ** length is 86399, 86400 or 86401 SI seconds. In the 1960-1972 era ** there were smaller jumps (in either direction) each time the ** linear UTC(TAI) expression was changed, and these "mini-leaps" ** are also included in the ERFA convention. ** ** 3) The warning status "dubious year" flags UTCs that predate the ** introduction of the time scale or that are too far in the future ** to be trusted. See eraDat for further details. ** ** 4) The function eraDtf2d converts from calendar date and time of day ** into 2-part Julian Date, and in the case of UTC implements the ** leap-second-ambiguity convention described above. ** ** 5) The returned TAI1,TAI2 are such that their sum is the TAI Julian ** Date. ** ** Called: ** eraJd2cal JD to Gregorian calendar ** eraDat delta(AT) = TAI-UTC ** eraCal2jd Gregorian calendar to JD ** ** References: ** ** McCarthy, D. D., Petit, G. (eds.), IERS Conventions (2003), ** IERS Technical Note No. 32, BKG (2004) ** ** Explanatory Supplement to the Astronomical Almanac, ** P. Kenneth Seidelmann (ed), University Science Books (1992) ** ** Copyright (C) 2013-2015, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { int big1; int iy, im, id, j, iyt, imt, idt; double u1, u2, fd, dat0, dat12, w, dat24, dlod, dleap, z1, z2, a2; /* Put the two parts of the UTC into big-first order. */ big1 = ( utc1 >= utc2 ); if ( big1 ) { u1 = utc1; u2 = utc2; } else { u1 = utc2; u2 = utc1; } /* Get TAI-UTC at 0h today. */ j = eraJd2cal(u1, u2, &iy, &im, &id, &fd); if ( j ) return j; j = eraDat(iy, im, id, 0.0, &dat0); if ( j < 0 ) return j; /* Get TAI-UTC at 12h today (to detect drift). */ j = eraDat(iy, im, id, 0.5, &dat12); if ( j < 0 ) return j; /* Get TAI-UTC at 0h tomorrow (to detect jumps). */ j = eraJd2cal(u1+1.5, u2-fd, &iyt, &imt, &idt, &w); if ( j ) return j; j = eraDat(iyt, imt, idt, 0.0, &dat24); if ( j < 0 ) return j; /* Separate TAI-UTC change into per-day (DLOD) and any jump (DLEAP). */ dlod = 2.0 * (dat12 - dat0); dleap = dat24 - (dat0 + dlod); /* Remove any scaling applied to spread leap into preceding day. */ fd *= (ERFA_DAYSEC+dleap)/ERFA_DAYSEC; /* Scale from (pre-1972) UTC seconds to SI seconds. */ fd *= (ERFA_DAYSEC+dlod)/ERFA_DAYSEC; /* Today's calendar date to 2-part JD. */ if ( eraCal2jd(iy, im, id, &z1, &z2) ) return -1; /* Assemble the TAI result, preserving the UTC split and order. */ a2 = z1 - u1; a2 += z2; a2 += fd + dat0/ERFA_DAYSEC; if ( big1 ) { *tai1 = u1; *tai2 = a2; } else { *tai1 = a2; *tai2 = u1; } /* Status. */ return j; }
int eraDtf2d(const char *scale, int iy, int im, int id, int ihr, int imn, double sec, double *d1, double *d2) /* ** - - - - - - - - - ** e r a D t f 2 d ** - - - - - - - - - ** ** Encode date and time fields into 2-part Julian Date (or in the case ** of UTC a quasi-JD form that includes special provision for leap ** seconds). ** ** Given: ** scale char[] time scale ID (Note 1) ** iy,im,id int year, month, day in Gregorian calendar (Note 2) ** ihr,imn int hour, minute ** sec double seconds ** ** Returned: ** d1,d2 double 2-part Julian Date (Notes 3,4) ** ** Returned (function value): ** int status: +3 = both of next two ** +2 = time is after end of day (Note 5) ** +1 = dubious year (Note 6) ** 0 = OK ** -1 = bad year ** -2 = bad month ** -3 = bad day ** -4 = bad hour ** -5 = bad minute ** -6 = bad second (<0) ** ** Notes: ** ** 1) scale identifies the time scale. Only the value "UTC" (in upper ** case) is significant, and enables handling of leap seconds (see ** Note 4). ** ** 2) For calendar conventions and limitations, see eraCal2jd. ** ** 3) The sum of the results, d1+d2, is Julian Date, where normally d1 ** is the Julian Day Number and d2 is the fraction of a day. In the ** case of UTC, where the use of JD is problematical, special ** conventions apply: see the next note. ** ** 4) JD cannot unambiguously represent UTC during a leap second unless ** special measures are taken. The ERFA internal convention is that ** the quasi-JD day represents UTC days whether the length is 86399, ** 86400 or 86401 SI seconds. In the 1960-1972 era there were ** smaller jumps (in either direction) each time the linear UTC(TAI) ** expression was changed, and these "mini-leaps" are also included ** in the ERFA convention. ** ** 5) The warning status "time is after end of day" usually means that ** the sec argument is greater than 60.0. However, in a day ending ** in a leap second the limit changes to 61.0 (or 59.0 in the case ** of a negative leap second). ** ** 6) The warning status "dubious year" flags UTCs that predate the ** introduction of the time scale or that are too far in the future ** to be trusted. See eraDat for further details. ** ** 7) Only in the case of continuous and regular time scales (TAI, TT, ** TCG, TCB and TDB) is the result d1+d2 a Julian Date, strictly ** speaking. In the other cases (UT1 and UTC) the result must be ** used with circumspection; in particular the difference between ** two such results cannot be interpreted as a precise time ** interval. ** ** Called: ** eraCal2jd Gregorian calendar to JD ** eraDat delta(AT) = TAI-UTC ** eraJd2cal JD to Gregorian calendar ** ** Copyright (C) 2013-2014, NumFOCUS Foundation. ** Derived, with permission, from the SOFA library. See notes at end of file. */ { int js, iy2, im2, id2; double dj, w, day, seclim, dat0, dat12, dat24, dleap, time; /* Today's Julian Day Number. */ js = eraCal2jd(iy, im, id, &dj, &w); if ( js ) return js; dj += w; /* Day length and final minute length in seconds (provisional). */ day = ERFA_DAYSEC; seclim = 60.0; /* Deal with the UTC leap second case. */ if ( ! strcmp(scale,"UTC") ) { /* TAI-UTC at 0h today. */ js = eraDat(iy, im, id, 0.0, &dat0); if ( js < 0 ) return js; /* TAI-UTC at 12h today (to detect drift). */ js = eraDat(iy, im, id, 0.5, &dat12); if ( js < 0 ) return js; /* TAI-UTC at 0h tomorrow (to detect jumps). */ js = eraJd2cal ( dj, 1.5, &iy2, &im2, &id2, &w); if ( js ) return js; js = eraDat(iy2, im2, id2, 0.0, &dat24); if ( js < 0 ) return js; /* Any sudden change in TAI-UTC between today and tomorrow. */ dleap = dat24 - (2.0*dat12 - dat0); /* If leap second day, correct the day and final minute lengths. */ day += dleap; if ( ihr == 23 && imn == 59 ) seclim += dleap; /* End of UTC-specific actions. */ } /* Validate the time. */ if ( ihr >= 0 && ihr <= 23 ) { if ( imn >= 0 && imn <= 59 ) { if ( sec >= 0 ) { if ( sec >= seclim ) { js += 2; } } else { js = -6; } } else { js = -5; } } else { js = -4; } if ( js < 0 ) return js; /* The time in days. */ time = ( 60.0 * ( (double) ( 60 * ihr + imn ) ) + sec ) / day; /* Return the date and time. */ *d1 = dj; *d2 = time; /* Status. */ return js; }