File Coverage

erfasrc/src/dat.c
Criterion Covered Total %
statement 16 16 100.0
branch 10 18 55.5
condition n/a
subroutine n/a
pod n/a
total 26 34 76.4


line stmt bran cond sub pod time code
1             #include "erfa.h"
2             #include "erfadatextra.h"
3              
4 4           int eraDat(int iy, int im, int id, double fd, double *deltat)
5             /*
6             ** - - - - - - -
7             ** e r a D a t
8             ** - - - - - - -
9             **
10             ** For a given UTC date, calculate Delta(AT) = TAI-UTC.
11             **
12             ** :------------------------------------------:
13             ** : :
14             ** : IMPORTANT :
15             ** : :
16             ** : A new version of this function must be :
17             ** : produced whenever a new leap second is :
18             ** : announced. There are four items to :
19             ** : change on each such occasion: :
20             ** : :
21             ** : 1) A new line must be added to the set :
22             ** : of statements that initialize the :
23             ** : array "changes". :
24             ** : :
25             ** : 2) The constant IYV must be set to the :
26             ** : current year. :
27             ** : :
28             ** : 3) The "Latest leap second" comment :
29             ** : below must be set to the new leap :
30             ** : second date. :
31             ** : :
32             ** : 4) The "This revision" comment, later, :
33             ** : must be set to the current date. :
34             ** : :
35             ** : Change (2) must also be carried out :
36             ** : whenever the function is re-issued, :
37             ** : even if no leap seconds have been :
38             ** : added. :
39             ** : :
40             ** : Latest leap second: 2016 December 31 :
41             ** : :
42             ** :__________________________________________:
43             **
44             ** Given:
45             ** iy int UTC: year (Notes 1 and 2)
46             ** im int month (Note 2)
47             ** id int day (Notes 2 and 3)
48             ** fd double fraction of day (Note 4)
49             **
50             ** Returned:
51             ** deltat double TAI minus UTC, seconds
52             **
53             ** Returned (function value):
54             ** int status (Note 5):
55             ** 1 = dubious year (Note 1)
56             ** 0 = OK
57             ** -1 = bad year
58             ** -2 = bad month
59             ** -3 = bad day (Note 3)
60             ** -4 = bad fraction (Note 4)
61             ** -5 = internal error (Note 5)
62             **
63             ** Notes:
64             **
65             ** 1) UTC began at 1960 January 1.0 (JD 2436934.5) and it is improper
66             ** to call the function with an earlier date. If this is attempted,
67             ** zero is returned together with a warning status.
68             **
69             ** Because leap seconds cannot, in principle, be predicted in
70             ** advance, a reliable check for dates beyond the valid range is
71             ** impossible. To guard against gross errors, a year five or more
72             ** after the release year of the present function (see the constant
73             ** IYV) is considered dubious. In this case a warning status is
74             ** returned but the result is computed in the normal way.
75             **
76             ** For both too-early and too-late years, the warning status is +1.
77             ** This is distinct from the error status -1, which signifies a year
78             ** so early that JD could not be computed.
79             **
80             ** 2) If the specified date is for a day which ends with a leap second,
81             ** the TAI-UTC value returned is for the period leading up to the
82             ** leap second. If the date is for a day which begins as a leap
83             ** second ends, the TAI-UTC returned is for the period following the
84             ** leap second.
85             **
86             ** 3) The day number must be in the normal calendar range, for example
87             ** 1 through 30 for April. The "almanac" convention of allowing
88             ** such dates as January 0 and December 32 is not supported in this
89             ** function, in order to avoid confusion near leap seconds.
90             **
91             ** 4) The fraction of day is used only for dates before the
92             ** introduction of leap seconds, the first of which occurred at the
93             ** end of 1971. It is tested for validity (0 to 1 is the valid
94             ** range) even if not used; if invalid, zero is used and status -4
95             ** is returned. For many applications, setting fd to zero is
96             ** acceptable; the resulting error is always less than 3 ms (and
97             ** occurs only pre-1972).
98             **
99             ** 5) The status value returned in the case where there are multiple
100             ** errors refers to the first error detected. For example, if the
101             ** month and day are 13 and 32 respectively, status -2 (bad month)
102             ** will be returned. The "internal error" status refers to a
103             ** case that is impossible but causes some compilers to issue a
104             ** warning.
105             **
106             ** 6) In cases where a valid result is not available, zero is returned.
107             **
108             ** References:
109             **
110             ** 1) For dates from 1961 January 1 onwards, the expressions from the
111             ** file ftp://maia.usno.navy.mil/ser7/tai-utc.dat are used.
112             **
113             ** 2) The 5ms timestep at 1961 January 1 is taken from 2.58.1 (p87) of
114             ** the 1992 Explanatory Supplement.
115             **
116             ** Called:
117             ** eraCal2jd Gregorian calendar to JD
118             **
119             ** Copyright (C) 2013-2020, NumFOCUS Foundation.
120             ** Derived, with permission, from the SOFA library. See notes at end of file.
121             */
122             {
123             /* Release year for this version of eraDat */
124             enum { IYV = 2020};
125              
126             /* Reference dates (MJD) and drift rates (s/day), pre leap seconds */
127             static const double drift[][2] = {
128             { 37300.0, 0.0012960 },
129             { 37300.0, 0.0012960 },
130             { 37300.0, 0.0012960 },
131             { 37665.0, 0.0011232 },
132             { 37665.0, 0.0011232 },
133             { 38761.0, 0.0012960 },
134             { 38761.0, 0.0012960 },
135             { 38761.0, 0.0012960 },
136             { 38761.0, 0.0012960 },
137             { 38761.0, 0.0012960 },
138             { 38761.0, 0.0012960 },
139             { 38761.0, 0.0012960 },
140             { 39126.0, 0.0025920 },
141             { 39126.0, 0.0025920 }
142             };
143              
144             /* Number of Delta(AT) expressions before leap seconds were introduced */
145             enum { NERA1 = (int) (sizeof drift / sizeof (double) / 2) };
146              
147             /* Dates and Delta(AT)s */
148             static const eraLEAPSECOND _changes[] = {
149             { 1960, 1, 1.4178180 },
150             { 1961, 1, 1.4228180 },
151             { 1961, 8, 1.3728180 },
152             { 1962, 1, 1.8458580 },
153             { 1963, 11, 1.9458580 },
154             { 1964, 1, 3.2401300 },
155             { 1964, 4, 3.3401300 },
156             { 1964, 9, 3.4401300 },
157             { 1965, 1, 3.5401300 },
158             { 1965, 3, 3.6401300 },
159             { 1965, 7, 3.7401300 },
160             { 1965, 9, 3.8401300 },
161             { 1966, 1, 4.3131700 },
162             { 1968, 2, 4.2131700 },
163             { 1972, 1, 10.0 },
164             { 1972, 7, 11.0 },
165             { 1973, 1, 12.0 },
166             { 1974, 1, 13.0 },
167             { 1975, 1, 14.0 },
168             { 1976, 1, 15.0 },
169             { 1977, 1, 16.0 },
170             { 1978, 1, 17.0 },
171             { 1979, 1, 18.0 },
172             { 1980, 1, 19.0 },
173             { 1981, 7, 20.0 },
174             { 1982, 7, 21.0 },
175             { 1983, 7, 22.0 },
176             { 1985, 7, 23.0 },
177             { 1988, 1, 24.0 },
178             { 1990, 1, 25.0 },
179             { 1991, 1, 26.0 },
180             { 1992, 7, 27.0 },
181             { 1993, 7, 28.0 },
182             { 1994, 7, 29.0 },
183             { 1996, 1, 30.0 },
184             { 1997, 7, 31.0 },
185             { 1999, 1, 32.0 },
186             { 2006, 1, 33.0 },
187             { 2009, 1, 34.0 },
188             { 2012, 7, 35.0 },
189             { 2015, 7, 36.0 },
190             { 2017, 1, 37.0 }
191             };
192              
193             /* Number of Delta(AT) changes */
194             enum { _NDAT = (int) (sizeof _changes / sizeof _changes[0]) };
195              
196             /* Get/initialise leap-second if needed */
197             int NDAT;
198             eraLEAPSECOND *changes;
199              
200 4           NDAT = eraDatini(_changes, _NDAT, &changes);
201              
202             /* Miscellaneous local variables */
203             int j, i, m;
204             double da, djm0, djm;
205              
206              
207             /* Initialize the result to zero. */
208 4           *deltat = da = 0.0;
209              
210             /* If invalid fraction of a day, set error status and give up. */
211 4 50         if (fd < 0.0 || fd > 1.0) return -4;
    50          
212              
213             /* Convert the date into an MJD. */
214 4           j = eraCal2jd(iy, im, id, &djm0, &djm);
215              
216             /* If invalid year, month, or day, give up. */
217 4 50         if (j < 0) return j;
218              
219             /* If pre-UTC year, set warning status and give up. */
220 4 50         if (iy < changes[0].iyear) return 1;
221              
222             /* If suspiciously late year, set warning status but proceed. */
223 4 50         if (iy > IYV + 5) j = 1;
224              
225             /* Combine year and month to form a date-ordered integer... */
226 4           m = 12*iy + im;
227              
228             /* ...and use it to find the preceding table entry. */
229 32 50         for (i = NDAT-1; i >=0; i--) {
230 32 100         if (m >= (12 * changes[i].iyear + changes[i].month)) break;
231             }
232              
233             /* Prevent underflow warnings. */
234 4 50         if (i < 0) return -5;
235              
236             /* Get the Delta(AT). */
237 4           da = changes[i].delat;
238              
239             /* If pre-1972, adjust for drift. */
240 4 50         if (i < NERA1) da += (djm + fd - drift[i][0]) * drift[i][1];
241              
242             /* Return the Delta(AT) value. */
243 4           *deltat = da;
244              
245             /* Return the status. */
246 4           return j;
247              
248             }
249             /*----------------------------------------------------------------------
250             **
251             **
252             ** Copyright (C) 2013-2020, NumFOCUS Foundation.
253             ** All rights reserved.
254             **
255             ** This library is derived, with permission, from the International
256             ** Astronomical Union's "Standards of Fundamental Astronomy" library,
257             ** available from http://www.iausofa.org.
258             **
259             ** The ERFA version is intended to retain identical functionality to
260             ** the SOFA library, but made distinct through different function and
261             ** file names, as set out in the SOFA license conditions. The SOFA
262             ** original has a role as a reference standard for the IAU and IERS,
263             ** and consequently redistribution is permitted only in its unaltered
264             ** state. The ERFA version is not subject to this restriction and
265             ** therefore can be included in distributions which do not support the
266             ** concept of "read only" software.
267             **
268             ** Although the intent is to replicate the SOFA API (other than
269             ** replacement of prefix names) and results (with the exception of
270             ** bugs; any that are discovered will be fixed), SOFA is not
271             ** responsible for any errors found in this version of the library.
272             **
273             ** If you wish to acknowledge the SOFA heritage, please acknowledge
274             ** that you are using a library derived from SOFA, rather than SOFA
275             ** itself.
276             **
277             **
278             ** TERMS AND CONDITIONS
279             **
280             ** Redistribution and use in source and binary forms, with or without
281             ** modification, are permitted provided that the following conditions
282             ** are met:
283             **
284             ** 1 Redistributions of source code must retain the above copyright
285             ** notice, this list of conditions and the following disclaimer.
286             **
287             ** 2 Redistributions in binary form must reproduce the above copyright
288             ** notice, this list of conditions and the following disclaimer in
289             ** the documentation and/or other materials provided with the
290             ** distribution.
291             **
292             ** 3 Neither the name of the Standards Of Fundamental Astronomy Board,
293             ** the International Astronomical Union nor the names of its
294             ** contributors may be used to endorse or promote products derived
295             ** from this software without specific prior written permission.
296             **
297             ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
298             ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
299             ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
300             ** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
301             ** COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
302             ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
303             ** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
304             ** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
305             ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
306             ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
307             ** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
308             ** POSSIBILITY OF SUCH DAMAGE.
309             **
310             */