1   /* Copyright 2002-2025 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.time;
18  
19  import org.junit.jupiter.api.Assertions;
20  import org.junit.jupiter.api.Test;
21  import org.orekit.Utils;
22  import org.orekit.errors.OrekitException;
23  import org.orekit.errors.OrekitMessages;
24  
25  public class TAIUTCDatAFilesLoaderTest {
26  
27      @Test
28      public void testRegularFile() {
29  
30          Utils.setDataRoot("USNO");
31  
32          // we arbitrary put UTC == TAI before 1961-01-01
33          checkOffset(1950,  1,  1,   0);
34  
35          // linear models between 1961 and 1972
36          checkOffset(1961,  1,  2,  -(1.422818 +   1 * 0.001296));  // MJD 37300 +   1
37          checkOffset(1961,  8,  2,  -(1.372818 + 213 * 0.001296));  // MJD 37300 + 213
38          checkOffset(1962,  1,  2,  -(1.845858 +   1 * 0.0011232)); // MJD 37665 +   1
39          checkOffset(1963, 11,  2,  -(1.945858 + 670 * 0.0011232)); // MJD 37665 + 670
40          checkOffset(1964,  1,  2,  -(3.240130 - 365 * 0.001296));  // MJD 38761 - 365
41          checkOffset(1964,  4,  2,  -(3.340130 - 274 * 0.001296));  // MJD 38761 - 274
42          checkOffset(1964,  9,  2,  -(3.440130 - 121 * 0.001296));  // MJD 38761 - 121
43          checkOffset(1965,  1,  2,  -(3.540130 +   1 * 0.001296));  // MJD 38761 +   1
44          checkOffset(1965,  3,  2,  -(3.640130 +  60 * 0.001296));  // MJD 38761 +  60
45          checkOffset(1965,  7,  2,  -(3.740130 + 182 * 0.001296));  // MJD 38761 + 182
46          checkOffset(1965,  9,  2,  -(3.840130 + 244 * 0.001296));  // MJD 38761 + 244
47          checkOffset(1966,  1,  2,  -(4.313170 +   1 * 0.002592));  // MJD 39126 +   1
48          checkOffset(1968,  2,  2,  -(4.213170 + 762 * 0.002592));  // MJD 39126 + 762
49  
50          // since 1972-01-01, offsets are only whole seconds
51          checkOffset(1972,  3,  5, -10);
52          checkOffset(1972,  7, 14, -11);
53          checkOffset(1979, 12, 31, -18);
54          checkOffset(1980,  1, 22, -19);
55          checkOffset(2006,  7,  7, -33);
56          checkOffset(2010,  7,  7, -34);
57          checkOffset(2012,  7,  7, -35);
58          checkOffset(2015,  7,  7, -36);
59  
60      }
61  
62      @Test
63      public void testOnlyPre1972Data() {
64  
65          Utils.setDataRoot("USNO");
66          TimeScalesFactory.addUTCTAIOffsetsLoader(new TAIUTCDatFilesLoader("tai-utc-only-pre-1972-data.dat"));
67  
68          // linear models between 1961 and 1972
69          checkOffset(1961,  1,  2,  -(1.422818 +   1 * 0.001296));  // MJD 37300 +   1
70          checkOffset(1961,  8,  2,  -(1.372818 + 213 * 0.001296));  // MJD 37300 + 213
71          checkOffset(1962,  1,  2,  -(1.845858 +   1 * 0.0011232)); // MJD 37665 +   1
72          checkOffset(1963, 11,  2,  -(1.945858 + 670 * 0.0011232)); // MJD 37665 + 670
73          checkOffset(1964,  1,  2,  -(3.240130 - 365 * 0.001296));  // MJD 38761 - 365
74          checkOffset(1964,  4,  2,  -(3.340130 - 274 * 0.001296));  // MJD 38761 - 274
75          checkOffset(1964,  9,  2,  -(3.440130 - 121 * 0.001296));  // MJD 38761 - 121
76          checkOffset(1965,  1,  2,  -(3.540130 +   1 * 0.001296));  // MJD 38761 +   1
77          checkOffset(1965,  3,  2,  -(3.640130 +  60 * 0.001296));  // MJD 38761 +  60
78          checkOffset(1965,  7,  2,  -(3.740130 + 182 * 0.001296));  // MJD 38761 + 182
79          checkOffset(1965,  9,  2,  -(3.840130 + 244 * 0.001296));  // MJD 38761 + 244
80          checkOffset(1966,  1,  2,  -(4.313170 +   1 * 0.002592));  // MJD 39126 +   1
81          checkOffset(1968,  2,  2,  -(4.213170 + 762 * 0.002592));  // MJD 39126 + 762
82  
83          // last linear drift is not stopped as we miss the first constant offset in 1972
84          checkOffset(1972,  3,  5,  -(4.213170 +  2255 * 0.002592));  // MJD 39126 +  2255
85          checkOffset(1972,  7, 14,  -(4.213170 +  2386 * 0.002592));  // MJD 39126 +  2386
86          checkOffset(1979, 12, 31,  -(4.213170 +  5112 * 0.002592));  // MJD 39126 +  5112
87          checkOffset(1980,  1, 22,  -(4.213170 +  5134 * 0.002592));  // MJD 39126 +  5134
88          checkOffset(2006,  7,  7,  -(4.213170 + 14797 * 0.002592));  // MJD 39126 + 14797
89          checkOffset(2010,  7,  7,  -(4.213170 + 16258 * 0.002592));  // MJD 39126 + 16258
90          checkOffset(2012,  7,  7,  -(4.213170 + 16989 * 0.002592));  // MJD 39126 + 16989
91          checkOffset(2015,  7,  7,  -(4.213170 + 18084 * 0.002592));  // MJD 39126 + 18084
92  
93      }
94  
95      @Test
96      public void testModifiedLinearData() {
97  
98          Utils.setDataRoot("USNO");
99          TimeScalesFactory.addUTCTAIOffsetsLoader(new TAIUTCDatFilesLoader("tai-utc-modified-linear.dat"));
100 
101         // linear models between 1961 and 1972
102         checkOffset(1961,  1,  2,  -(1.4000000 +   1 * 0.000864));  // MJD 37300 +   1
103         checkOffset(1961,  8,  2,  -(1.5000000 + 213 * 0.001296));  // MJD 37300 + 213
104         checkOffset(1962,  1,  2,  -(1.6000000 +   1 * 0.001728));  // MJD 37665 +   1
105         checkOffset(1963, 11,  2,  -(1.7000000 + 670 * 0.002160));  // MJD 37665 + 670
106         checkOffset(1964,  1,  2,  -(1.8000000 - 365 * 0.002592));  // MJD 38761 - 365
107         checkOffset(1964,  4,  2,  -(1.9000000 - 274 * 0.003024));  // MJD 38761 - 274
108         checkOffset(1964,  9,  2,  -(2.0000000 - 121 * 0.003456));  // MJD 38761 - 121
109         checkOffset(1965,  1,  2,  -(2.1000000 +   1 * 0.003888));  // MJD 38761 +   1
110         checkOffset(1965,  3,  2,  -(2.2000000 +  60 * 0.004320));  // MJD 38761 +  60
111         checkOffset(1965,  7,  2,  -(2.3000000 + 182 * 0.004752));  // MJD 38761 + 182
112         checkOffset(1965,  9,  2,  -(2.4000000 + 244 * 0.005184));  // MJD 38761 + 244
113         checkOffset(1966,  1,  2,  -(2.5000000 +   1 * 0.005616));  // MJD 39126 +   1
114         checkOffset(1968,  2,  2,  -(2.6000000 + 762 * 0.006048));  // MJD 39126 + 762
115 
116         // last linear drift is not stopped as we miss the first constant offset in 1972
117         checkOffset(1972,  3,  5,  -(2.6000000 +  2255 * 0.006048));  // MJD 39126 +  2255
118         checkOffset(1972,  7, 14,  -(2.6000000 +  2386 * 0.006048));  // MJD 39126 +  2386
119         checkOffset(1979, 12, 31,  -(2.6000000 +  5112 * 0.006048));  // MJD 39126 +  5112
120         checkOffset(1980,  1, 22,  -(2.6000000 +  5134 * 0.006048));  // MJD 39126 +  5134
121         checkOffset(2006,  7,  7,  -(2.6000000 + 14797 * 0.006048));  // MJD 39126 + 14797
122         checkOffset(2010,  7,  7,  -(2.6000000 + 16258 * 0.006048));  // MJD 39126 + 16258
123         checkOffset(2012,  7,  7,  -(2.6000000 + 16989 * 0.006048));  // MJD 39126 + 16989
124         checkOffset(2015,  7,  7,  -(2.6000000 + 18084 * 0.006048));  // MJD 39126 + 18084
125 
126     }
127 
128     @Test
129     public void testInconsistentDate() {
130         checkException("tai-utc-inconsistent-date.dat",
131                        OrekitMessages.INCONSISTENT_DATES_IN_IERS_FILE);
132     }
133 
134     @Test
135     public void testNonChronological() {
136         checkException("tai-utc-non-chronological.dat",
137                        OrekitMessages.NON_CHRONOLOGICAL_DATES_IN_FILE);
138     }
139 
140     @Test
141     public void testFormatError() {
142         checkException("tai-utc-format-error.dat",
143                        OrekitMessages.UNABLE_TO_PARSE_LINE_IN_FILE);
144     }
145 
146     private void checkOffset(int year, int month, int day, double offset) {
147         TimeScale utc = TimeScalesFactory.getUTC();
148         AbsoluteDate date = new AbsoluteDate(year, month, day, utc);
149         Assertions.assertEquals(offset, utc.offsetFromTAI(date).toDouble(), 1.0e-10);
150     }
151 
152     private void checkException(String name, OrekitMessages message) {
153         Utils.setDataRoot("USNO");
154         TimeScalesFactory.addUTCTAIOffsetsLoader(new TAIUTCDatFilesLoader(name));
155         try {
156             TimeScalesFactory.getUTC();
157             Assertions.fail("an exception should have been thrown");
158         } catch (OrekitException oe) {
159             Assertions.assertEquals(message, oe.getSpecifier());
160         }
161     }
162 
163 }