1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.time;
18
19 import java.io.IOException;
20 import java.lang.reflect.Field;
21 import java.sql.Timestamp;
22 import java.text.DecimalFormat;
23 import java.text.DecimalFormatSymbols;
24 import java.time.Instant;
25 import java.time.LocalDateTime;
26 import java.time.OffsetDateTime;
27 import java.time.ZoneOffset;
28 import java.time.ZonedDateTime;
29 import java.time.format.DateTimeFormatter;
30 import java.util.Date;
31 import java.util.Locale;
32 import java.util.TimeZone;
33
34 import java.util.concurrent.TimeUnit;
35 import org.hamcrest.CoreMatchers;
36 import org.hamcrest.MatcherAssert;
37 import org.hipparchus.util.FastMath;
38 import org.hipparchus.util.Precision;
39 import org.junit.jupiter.api.Assertions;
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42 import org.orekit.OrekitMatchers;
43 import org.orekit.Utils;
44 import org.orekit.data.DataContext;
45 import org.orekit.errors.OrekitException;
46 import org.orekit.errors.OrekitIllegalArgumentException;
47 import org.orekit.errors.OrekitMessages;
48 import org.orekit.utils.Constants;
49
50 public class AbsoluteDateTest {
51
52 @Test
53 public void testStandardEpoch() {
54 TimeScale tai = TimeScalesFactory.getTAI();
55 TimeScale tt = TimeScalesFactory.getTT();
56 Assertions.assertEquals(-210866760000000l, AbsoluteDate.JULIAN_EPOCH.toDate(tt).getTime());
57 Assertions.assertEquals(-3506716800000l, AbsoluteDate.MODIFIED_JULIAN_EPOCH.toDate(tt).getTime());
58 Assertions.assertEquals(-631152000000l, AbsoluteDate.FIFTIES_EPOCH.toDate(tt).getTime());
59 Assertions.assertEquals(-378691200000l, AbsoluteDate.CCSDS_EPOCH.toDate(tai).getTime());
60 Assertions.assertEquals(935280019000l, AbsoluteDate.GALILEO_EPOCH.toDate(tai).getTime());
61 Assertions.assertEquals(315964819000l, AbsoluteDate.GPS_EPOCH.toDate(tai).getTime());
62 Assertions.assertEquals(315964819000l, AbsoluteDate.QZSS_EPOCH.toDate(tai).getTime());
63 Assertions.assertEquals(1136073633000l, AbsoluteDate.BEIDOU_EPOCH.toDate(tai).getTime());
64 Assertions.assertEquals(820443629000l, AbsoluteDate.GLONASS_EPOCH.toDate(tai).getTime());
65 Assertions.assertEquals(935280019000l, AbsoluteDate.IRNSS_EPOCH.toDate(tai).getTime());
66 Assertions.assertEquals(946728000000l, AbsoluteDate.J2000_EPOCH.toDate(tt).getTime());
67 }
68
69 @Test
70 public void testStandardEpochStrings() {
71 Assertions.assertEquals("-4712-01-01T12:00:00.000",
72 AbsoluteDate.JULIAN_EPOCH.toString(TimeScalesFactory.getTT()));
73 Assertions.assertEquals("1858-11-17T00:00:00.000",
74 AbsoluteDate.MODIFIED_JULIAN_EPOCH.toString(TimeScalesFactory.getTT()));
75 Assertions.assertEquals("1950-01-01T00:00:00.000",
76 AbsoluteDate.FIFTIES_EPOCH.toString(TimeScalesFactory.getTT()));
77 Assertions.assertEquals("1958-01-01T00:00:00.000",
78 AbsoluteDate.CCSDS_EPOCH.toString(TimeScalesFactory.getTAI()));
79 Assertions.assertEquals("1999-08-21T23:59:47.000",
80 AbsoluteDate.GALILEO_EPOCH.toString(TimeScalesFactory.getUTC()));
81 Assertions.assertEquals("1980-01-06T00:00:00.000",
82 AbsoluteDate.GPS_EPOCH.toString(TimeScalesFactory.getUTC()));
83 Assertions.assertEquals("1980-01-06T00:00:00.000",
84 AbsoluteDate.QZSS_EPOCH.toString(TimeScalesFactory.getUTC()));
85 Assertions.assertEquals("2006-01-01T00:00:00.000",
86 AbsoluteDate.BEIDOU_EPOCH.toString(TimeScalesFactory.getUTC()));
87 Assertions.assertEquals("1995-12-31T21:00:00.000",
88 AbsoluteDate.GLONASS_EPOCH.toString(TimeScalesFactory.getUTC()));
89 Assertions.assertEquals("1999-08-21T23:59:47.000",
90 AbsoluteDate.IRNSS_EPOCH.toString(TimeScalesFactory.getUTC()));
91 Assertions.assertEquals("2000-01-01T12:00:00.000",
92 AbsoluteDate.J2000_EPOCH.toString(TimeScalesFactory.getTT()));
93 Assertions.assertEquals("1970-01-01T00:00:00.000",
94 AbsoluteDate.JAVA_EPOCH.toString(TimeScalesFactory.getUTC()));
95 }
96
97 @Test
98 public void testJulianEpochRate() {
99
100 for (int i = 0; i < 10; ++i) {
101 AbsoluteDate j200i = AbsoluteDate.createJulianEpoch(2000.0 + i);
102 AbsoluteDate j2000 = AbsoluteDate.J2000_EPOCH;
103 double expected = i * Constants.JULIAN_YEAR;
104 Assertions.assertEquals(expected, j200i.durationFrom(j2000), 4.0e-15 * expected);
105 }
106
107 }
108
109 @Test
110 public void testBesselianEpochRate() {
111
112 for (int i = 0; i < 10; ++i) {
113 AbsoluteDate b195i = AbsoluteDate.createBesselianEpoch(1950.0 + i);
114 AbsoluteDate b1950 = AbsoluteDate.createBesselianEpoch(1950.0);
115 double expected = i * Constants.BESSELIAN_YEAR;
116 Assertions.assertEquals(expected, b195i.durationFrom(b1950), 4.0e-15 * expected);
117 }
118
119 }
120
121 @Test
122 public void testLieske() {
123
124
125
126
127
128
129
130 final double publishedEpsilon = 1.0e-6 * Constants.JULIAN_YEAR;
131 checkEpochs(1899.999142, 1900.000000, publishedEpsilon);
132 checkEpochs(1900.000000, 1900.000858, publishedEpsilon);
133 checkEpochs(1950.000000, 1949.999790, publishedEpsilon);
134 checkEpochs(1950.000210, 1950.000000, publishedEpsilon);
135 checkEpochs(2000.000000, 1999.998722, publishedEpsilon);
136 checkEpochs(2000.001278, 2000.000000, publishedEpsilon);
137
138
139 final double accurateEpsilon = 1.2e-13 * Constants.JULIAN_YEAR;
140 checkEpochs(1899.99914161068724704, 1900.00000000000000000, accurateEpsilon);
141 checkEpochs(1900.00000000000000000, 1900.00085837097878165, accurateEpsilon);
142 checkEpochs(1950.00000000000000000, 1949.99979044229979466, accurateEpsilon);
143 checkEpochs(1950.00020956217615449, 1950.00000000000000000, accurateEpsilon);
144 checkEpochs(2000.00000000000000000, 1999.99872251362080766, accurateEpsilon);
145 checkEpochs(2000.00127751366506194, 2000.00000000000000000, accurateEpsilon);
146
147 }
148
149 private void checkEpochs(final double besselianEpoch, final double julianEpoch, final double epsilon) {
150 final AbsoluteDate b = AbsoluteDate.createBesselianEpoch(besselianEpoch);
151 final AbsoluteDate j = AbsoluteDate.createJulianEpoch(julianEpoch);
152 Assertions.assertEquals(0.0, b.durationFrom(j), epsilon);
153 }
154
155 @Test
156 public void testParse() {
157 Assertions.assertEquals(AbsoluteDate.MODIFIED_JULIAN_EPOCH,
158 new AbsoluteDate("1858-W46-3", TimeScalesFactory.getTT()));
159 Assertions.assertEquals(AbsoluteDate.JULIAN_EPOCH,
160 new AbsoluteDate("-4712-01-01T12:00:00.000", TimeScalesFactory.getTT()));
161 Assertions.assertEquals(AbsoluteDate.FIFTIES_EPOCH,
162 new AbsoluteDate("1950-01-01", TimeScalesFactory.getTT()));
163 Assertions.assertEquals(AbsoluteDate.CCSDS_EPOCH,
164 new AbsoluteDate("1958-001", TimeScalesFactory.getTAI()));
165 }
166
167 @Test
168 public void testLocalTimeParsing() {
169 TimeScale utc = TimeScalesFactory.getUTC();
170 Assertions.assertEquals(new AbsoluteDate("2011-12-31T23:00:00", utc),
171 new AbsoluteDate("2012-01-01T03:30:00+04:30", utc));
172 Assertions.assertEquals(new AbsoluteDate("2011-12-31T23:00:00", utc),
173 new AbsoluteDate("2012-01-01T03:30:00+0430", utc));
174 Assertions.assertEquals(new AbsoluteDate("2011-12-31T23:30:00", utc),
175 new AbsoluteDate("2012-01-01T03:30:00+04", utc));
176 Assertions.assertEquals(new AbsoluteDate("2012-01-01T05:17:00", utc),
177 new AbsoluteDate("2011-12-31T22:17:00-07:00", utc));
178 Assertions.assertEquals(new AbsoluteDate("2012-01-01T05:17:00", utc),
179 new AbsoluteDate("2011-12-31T22:17:00-0700", utc));
180 Assertions.assertEquals(new AbsoluteDate("2012-01-01T05:17:00", utc),
181 new AbsoluteDate("2011-12-31T22:17:00-07", utc));
182 }
183
184 @Test
185 public void testTimeZoneDisplay() {
186 final TimeScale utc = TimeScalesFactory.getUTC();
187 final AbsoluteDate date = new AbsoluteDate("2000-01-01T01:01:01.000", utc);
188 Assertions.assertEquals("2000-01-01T01:01:01.000Z", date.toString());
189 Assertions.assertEquals("2000-01-01T11:01:01.000+10:00", date.toString( 600));
190 Assertions.assertEquals("1999-12-31T23:01:01.000-02:00", date.toString(-120));
191 Assertions.assertEquals("2000-01-01T01:01:01.000+00:00", date.toString(0));
192
193
194 TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
195 Assertions.assertEquals("2001-01-22T11:30:00.000+01:00",
196 new AbsoluteDate("2001-01-22T10:30:00", utc).toString(tz));
197
198
199 Assertions.assertEquals("2001-06-23T11:30:00.000+02:00",
200 new AbsoluteDate("2001-06-23T09:30:00", utc).toString(tz));
201
202
203 tz = TimeZone.getTimeZone("UTC");
204 Assertions.assertEquals("2001-06-23T09:30:00.000+00:00",
205 new AbsoluteDate("2001-06-23T09:30:00", utc).toString(tz));
206
207 }
208
209 @Test
210 public void testLocalTimeLeapSecond() throws IOException {
211
212 TimeScale utc = TimeScalesFactory.getUTC();
213 AbsoluteDate beforeLeap = new AbsoluteDate("2012-06-30T23:59:59.8", utc);
214 AbsoluteDate inLeap = new AbsoluteDate("2012-06-30T23:59:60.5", utc);
215 Assertions.assertEquals(0.7, inLeap.durationFrom(beforeLeap), 1.0e-12);
216 for (int minutesFromUTC = -1500; minutesFromUTC < 1500; ++minutesFromUTC) {
217 DateTimeComponents dtcBeforeLeap = beforeLeap.getComponents(minutesFromUTC);
218 DateTimeComponents dtcInsideLeap = inLeap.getComponents(minutesFromUTC);
219 Assertions.assertEquals(dtcBeforeLeap.getDate(), dtcInsideLeap.getDate());
220 Assertions.assertEquals(dtcBeforeLeap.getTime().getHour(), dtcInsideLeap.getTime().getHour());
221 Assertions.assertEquals(dtcBeforeLeap.getTime().getMinute(), dtcInsideLeap.getTime().getMinute());
222 Assertions.assertEquals(minutesFromUTC, dtcBeforeLeap.getTime().getMinutesFromUTC());
223 Assertions.assertEquals(minutesFromUTC, dtcInsideLeap.getTime().getMinutesFromUTC());
224 Assertions.assertEquals(59.8, dtcBeforeLeap.getTime().getSecond(), 1.0e-10);
225 Assertions.assertEquals(60.5, dtcInsideLeap.getTime().getSecond(), 1.0e-10);
226 }
227
228 }
229
230 @Test
231 public void testTimeZoneLeapSecond() {
232
233 TimeScale utc = TimeScalesFactory.getUTC();
234 final TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
235 AbsoluteDate localBeforeMidnight = new AbsoluteDate("2012-06-30T21:59:59.800", utc);
236 Assertions.assertEquals("2012-06-30T23:59:59.800+02:00",
237 localBeforeMidnight.toString(tz));
238 Assertions.assertEquals("2012-07-01T00:00:00.800+02:00",
239 localBeforeMidnight.shiftedBy(1.0).toString(tz));
240
241 AbsoluteDate beforeLeap = new AbsoluteDate("2012-06-30T23:59:59.8", utc);
242 AbsoluteDate inLeap = new AbsoluteDate("2012-06-30T23:59:60.5", utc);
243 Assertions.assertEquals(0.7, inLeap.durationFrom(beforeLeap), 1.0e-12);
244 Assertions.assertEquals("2012-07-01T01:59:59.800+02:00", beforeLeap.toString(tz));
245 Assertions.assertEquals("2012-07-01T01:59:60.500+02:00", inLeap.toString(tz));
246
247 }
248
249 @Test
250 public void testParseLeap() {
251 TimeScale utc = TimeScalesFactory.getUTC();
252 AbsoluteDate beforeLeap = new AbsoluteDate("2012-06-30T23:59:59.8", utc);
253 AbsoluteDate inLeap = new AbsoluteDate("2012-06-30T23:59:60.5", utc);
254 Assertions.assertEquals(0.7, inLeap.durationFrom(beforeLeap), 1.0e-12);
255 Assertions.assertEquals("2012-06-30T23:59:60.500", inLeap.toString(utc));
256 }
257
258 @Test
259 public void testOutput() {
260 TimeScale tt = TimeScalesFactory.getTT();
261 Assertions.assertEquals("1950-01-01T01:01:01.000",
262 AbsoluteDate.FIFTIES_EPOCH.shiftedBy(3661.0).toString(tt));
263 Assertions.assertEquals("2000-01-01T13:01:01.000",
264 AbsoluteDate.J2000_EPOCH.shiftedBy(3661.0).toString(tt));
265 }
266
267 @Test
268 public void testJ2000() {
269 Assertions.assertEquals("2000-01-01T12:00:00.000",
270 AbsoluteDate.J2000_EPOCH.toString(TimeScalesFactory.getTT()));
271 Assertions.assertEquals("2000-01-01T11:59:27.816",
272 AbsoluteDate.J2000_EPOCH.toString(TimeScalesFactory.getTAI()));
273 Assertions.assertEquals("2000-01-01T11:58:55.816",
274 AbsoluteDate.J2000_EPOCH.toString(utc));
275 }
276
277 @Test
278 public void testFraction() {
279 AbsoluteDate d =
280 new AbsoluteDate(new DateComponents(2000, 01, 01), new TimeComponents(11, 59, 27.816),
281 TimeScalesFactory.getTAI());
282 Assertions.assertEquals(0, d.durationFrom(AbsoluteDate.J2000_EPOCH), 1.0e-10);
283 }
284
285 @Test
286 public void testScalesOffset() {
287 AbsoluteDate date = new AbsoluteDate(new DateComponents(2006, 02, 24),
288 new TimeComponents(15, 38, 00),
289 utc);
290 Assertions.assertEquals(33,
291 date.timeScalesOffset(TimeScalesFactory.getTAI(), utc),
292 1.0e-10);
293 }
294
295 @Test
296 public void testUTC() {
297 AbsoluteDate date = new AbsoluteDate(new DateComponents(2002, 01, 01),
298 new TimeComponents(00, 00, 01),
299 utc);
300 Assertions.assertEquals("2002-01-01T00:00:01.000Z", date.toString());
301 }
302
303 @Test
304 public void test1970() {
305 AbsoluteDate date = new AbsoluteDate(new Date(0l), utc);
306 Assertions.assertEquals("1970-01-01T00:00:00.000Z", date.toString());
307 }
308
309 @Test
310 public void test1970Instant() {
311 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new AbsoluteDate(Instant.EPOCH, utc).toString());
312 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new AbsoluteDate(Instant.ofEpochMilli(0l), utc).toString());
313 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new AbsoluteDate(Instant.EPOCH, (UTCScale) utc).toString());
314 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new AbsoluteDate(Instant.ofEpochMilli(0l), (UTCScale) utc).toString());
315 }
316
317 @Test
318 public void testInstantAccuracy() {
319 Assertions.assertEquals("1970-01-02T00:16:40.123456789Z", new AbsoluteDate(Instant.ofEpochSecond(87400, 123456789), utc).toString());
320 Assertions.assertEquals("1970-01-07T00:10:00.123456789Z", new AbsoluteDate(Instant.ofEpochSecond(519000, 123456789), utc).toString());
321 Assertions.assertEquals("1970-01-02T00:16:40.123456789Z", new AbsoluteDate(Instant.ofEpochSecond(87400, 123456789), (UTCScale) utc).toString());
322 Assertions.assertEquals("1970-01-07T00:10:00.123456789Z", new AbsoluteDate(Instant.ofEpochSecond(519000, 123456789), (UTCScale) utc).toString());
323 }
324
325 @Test
326 public void testToInstant() {
327 Assertions.assertEquals(Instant.ofEpochSecond(0), new AbsoluteDate("1970-01-01T00:00:00.000Z", utc).toInstant());
328 Assertions.assertEquals(Instant.ofEpochSecond(0), new AbsoluteDate("1970-01-01T00:00:00.000Z", utc).toInstant(TimeScalesFactory.getTimeScales()));
329
330 Instant expectedInstant = Instant.ofEpochSecond(519000, 123456789);
331 Assertions.assertEquals(expectedInstant, new AbsoluteDate("1970-01-07T00:10:00.123456789Z", utc).toInstant());
332 Assertions.assertEquals(expectedInstant, new AbsoluteDate("1970-01-07T00:10:00.123456789Z", utc).toInstant(TimeScalesFactory.getTimeScales()));
333
334 Assertions.assertEquals(OffsetDateTime.parse("2024-05-15T09:32:36.123456789Z", DateTimeFormatter.ISO_DATE_TIME).toInstant(),
335 new AbsoluteDate("2024-05-15T09:32:36.123456789Z", utc).toInstant());
336 Assertions.assertEquals(OffsetDateTime.parse("2024-05-15T09:32:36.123456789Z", DateTimeFormatter.ISO_DATE_TIME).toInstant(),
337 new AbsoluteDate("2024-05-15T09:32:36.123456789Z", utc).toInstant(TimeScalesFactory.getTimeScales()));
338 }
339
340 @Test
341 public void testUtcGpsOffset() {
342 AbsoluteDate date1 = new AbsoluteDate(new DateComponents(2005, 8, 9),
343 new TimeComponents(16, 31, 17),
344 utc);
345 AbsoluteDate date2 = new AbsoluteDate(new DateComponents(2006, 8, 9),
346 new TimeComponents(16, 31, 17),
347 utc);
348 AbsoluteDate dateRef = new AbsoluteDate(new DateComponents(1980, 1, 6),
349 TimeComponents.H00,
350 utc);
351
352
353 long noLeapGap = ((9347 * 24 + 16) * 60 + 31) * 60 + 17;
354 long realGap = (long) date1.durationFrom(dateRef);
355 Assertions.assertEquals(13l, realGap - noLeapGap);
356
357
358 noLeapGap = ((9712 * 24 + 16) * 60 + 31) * 60 + 17;
359 realGap = (long) date2.durationFrom(dateRef);
360 Assertions.assertEquals(14l, realGap - noLeapGap);
361
362 }
363
364 @Test
365 public void testMJDDate() {
366 AbsoluteDate dateA = AbsoluteDate.createMJDDate(51544, 0.5 * Constants.JULIAN_DAY,
367 TimeScalesFactory.getTT());
368 Assertions.assertEquals(0.0, AbsoluteDate.J2000_EPOCH.durationFrom(dateA), 1.0e-15);
369 AbsoluteDate dateB = AbsoluteDate.createMJDDate(53774, 0.0, TimeScalesFactory.getUTC());
370 AbsoluteDate dateC = new AbsoluteDate("2006-02-08T00:00:00", TimeScalesFactory.getUTC());
371 Assertions.assertEquals(0.0, dateC.durationFrom(dateB), 1.0e-15);
372 }
373
374 @Test
375 public void testJDDate() {
376 final AbsoluteDate date = AbsoluteDate.createJDDate(2400000, 0.5 * Constants.JULIAN_DAY,
377 TimeScalesFactory.getTT());
378 Assertions.assertEquals(0.0, AbsoluteDate.MODIFIED_JULIAN_EPOCH.durationFrom(date), 1.0e-15);
379 }
380
381
382 @Test
383 public void testIssue1310JDDateInTDB() {
384
385
386 final TDBScale TDBscale = TimeScalesFactory.getTDB();
387 final AbsoluteDate refDate = new AbsoluteDate("2023-08-01T00:00:00.000", TDBscale);
388
389
390
391 final AbsoluteDate wrongDate = AbsoluteDate.createJDDate(2460157,
392 Constants.JULIAN_DAY / 2.0d, TDBscale);
393 final AbsoluteDate properDate = AbsoluteDate.createJDDate(2460157,
394 Constants.JULIAN_DAY/2.0d, TDBscale, TimeScalesFactory.getTT());
395
396
397
398
399
400 Assertions.assertEquals(0.0, wrongDate.durationFrom(refDate), 1.270e-05);
401
402
403 Assertions.assertEquals(0.0, properDate.durationFrom(refDate), 2.132e-13);
404 }
405
406 @Test
407 public void testOffsets() {
408 final TimeScale tai = TimeScalesFactory.getTAI();
409 AbsoluteDate leapStartUTC = new AbsoluteDate(1976, 12, 31, 23, 59, 59, utc);
410 AbsoluteDate leapEndUTC = new AbsoluteDate(1977, 1, 1, 0, 0, 0, utc);
411 AbsoluteDate leapStartTAI = new AbsoluteDate(1977, 1, 1, 0, 0, 14, tai);
412 AbsoluteDate leapEndTAI = new AbsoluteDate(1977, 1, 1, 0, 0, 16, tai);
413 Assertions.assertEquals(leapStartUTC, leapStartTAI);
414 Assertions.assertEquals(leapEndUTC, leapEndTAI);
415 Assertions.assertEquals(1, leapEndUTC.offsetFrom(leapStartUTC, utc), 1.0e-10);
416 Assertions.assertEquals(1, leapEndTAI.offsetFrom(leapStartTAI, utc), 1.0e-10);
417 Assertions.assertEquals(2, leapEndUTC.offsetFrom(leapStartUTC, tai), 1.0e-10);
418 Assertions.assertEquals(2, leapEndTAI.offsetFrom(leapStartTAI, tai), 1.0e-10);
419 Assertions.assertEquals(2, leapEndUTC.durationFrom(leapStartUTC), 1.0e-10);
420 Assertions.assertEquals(2, leapEndTAI.durationFrom(leapStartTAI), 1.0e-10);
421 }
422
423 @Test
424 public void testBeforeAndAfterLeap() {
425 final TimeScale tai = TimeScalesFactory.getTAI();
426 AbsoluteDate leapStart = new AbsoluteDate(1977, 1, 1, 0, 0, 14, tai);
427 AbsoluteDate leapEnd = new AbsoluteDate(1977, 1, 1, 0, 0, 16, tai);
428 for (int i = -10; i < 10; ++i) {
429 final double dt = 1.1 * (2 * i - 1);
430 AbsoluteDate d1 = leapStart.shiftedBy(dt);
431 AbsoluteDate d2 = new AbsoluteDate(leapStart, dt, tai);
432 AbsoluteDate d3 = new AbsoluteDate(leapStart, dt, utc);
433 AbsoluteDate d4 = new AbsoluteDate(leapEnd, dt, tai);
434 AbsoluteDate d5 = new AbsoluteDate(leapEnd, dt, utc);
435 Assertions.assertTrue(FastMath.abs(d1.durationFrom(d2)) < 1.0e-10);
436 if (dt < 0) {
437 Assertions.assertTrue(FastMath.abs(d2.durationFrom(d3)) < 1.0e-10);
438 Assertions.assertTrue(d4.durationFrom(d5) > (1.0 - 1.0e-10));
439 } else {
440 Assertions.assertTrue(d2.durationFrom(d3) < (-1.0 + 1.0e-10));
441 Assertions.assertTrue(FastMath.abs(d4.durationFrom(d5)) < 1.0e-10);
442 }
443 }
444 }
445
446 @Test
447 public void testSymmetry() {
448 final TimeScale tai = TimeScalesFactory.getTAI();
449 AbsoluteDate leapStart = new AbsoluteDate(1977, 1, 1, 0, 0, 14, tai);
450 for (int i = -10; i < 10; ++i) {
451 final double dt = 1.1 * (2 * i - 1);
452 Assertions.assertEquals(dt, new AbsoluteDate(leapStart, dt, utc).offsetFrom(leapStart, utc), 1.0e-10);
453 Assertions.assertEquals(dt, new AbsoluteDate(leapStart, dt, tai).offsetFrom(leapStart, tai), 1.0e-10);
454 Assertions.assertEquals(dt, leapStart.shiftedBy(dt).durationFrom(leapStart), 1.0e-10);
455 }
456 }
457
458 @SuppressWarnings("unlikely-arg-type")
459 @Test
460 public void testEquals() {
461 AbsoluteDate d1 =
462 new AbsoluteDate(new DateComponents(2006, 2, 25),
463 new TimeComponents(17, 10, 34),
464 utc);
465 AbsoluteDate d2 = new AbsoluteDate(new DateComponents(2006, 2, 25),
466 new TimeComponents(17, 10, 0),
467 utc).shiftedBy(34);
468 Assertions.assertTrue(d1.equals(d2));
469 Assertions.assertFalse(d1.equals(this));
470 }
471
472 @Test
473 public void testComponents() {
474
475
476 DateComponents date = new DateComponents(2000, 1, 1);
477 TimeComponents time = new TimeComponents(11, 59, 10);
478 TimeScale[] scales = {
479 TimeScalesFactory.getTAI(), TimeScalesFactory.getUTC(),
480 TimeScalesFactory.getTT(), TimeScalesFactory.getTCG()
481 };
482 for (int i = 0; i < scales.length; ++i) {
483 AbsoluteDate in = new AbsoluteDate(date, time, scales[i]);
484 for (int j = 0; j < scales.length; ++j) {
485 DateTimeComponents pair = in.getComponents(scales[j]);
486 if (i == j) {
487 Assertions.assertEquals(date, pair.getDate());
488 Assertions.assertEquals(time, pair.getTime());
489 } else {
490 Assertions.assertNotSame(date, pair.getDate());
491 Assertions.assertNotSame(time, pair.getTime());
492 }
493 }
494 }
495 }
496
497 @Test
498 public void testMonth() {
499 TimeScale utc = TimeScalesFactory.getUTC();
500 Assertions.assertEquals(new AbsoluteDate(2011, 2, 23, utc),
501 new AbsoluteDate(2011, Month.FEBRUARY, 23, utc));
502 Assertions.assertEquals(new AbsoluteDate(2011, 2, 23, 1, 2, 3.4, utc),
503 new AbsoluteDate(2011, Month.FEBRUARY, 23, 1, 2, 3.4, utc));
504 }
505
506 @Test
507 public void testCCSDSUnsegmentedNoExtension() {
508
509 AbsoluteDate reference = new AbsoluteDate("2002-05-23T12:34:56.789", utc);
510 double lsb = FastMath.pow(2.0, -24);
511
512 byte[] timeCCSDSEpoch = new byte[] { 0x53, 0x7F, 0x40, -0x70, -0x37, -0x05, -0x19 };
513 for (int preamble = 0x00; preamble < 0x80; ++preamble) {
514 if (preamble == 0x1F) {
515
516 AbsoluteDate ccsds1 =
517 AbsoluteDate.parseCCSDSUnsegmentedTimeCode((byte) preamble, (byte) 0x0, timeCCSDSEpoch, null);
518 Assertions.assertEquals(0, ccsds1.durationFrom(reference), lsb / 2);
519 } else {
520 try {
521 AbsoluteDate.parseCCSDSUnsegmentedTimeCode((byte) preamble, (byte) 0x0, timeCCSDSEpoch, null);
522 Assertions.fail("an exception should have been thrown");
523 } catch (OrekitException iae) {
524
525 }
526
527 }
528 }
529
530
531 byte[] timeJ2000Epoch = new byte[] { 0x04, 0x7E, -0x0B, -0x10, -0x07, 0x16, -0x79 };
532 try {
533 AbsoluteDate.parseCCSDSUnsegmentedTimeCode((byte) 0x2F, (byte) 0x0, timeJ2000Epoch, null);
534 Assertions.fail("an exception should have been thrown");
535 } catch (OrekitException iae) {
536
537 }
538
539
540 AbsoluteDate ccsds3 =
541 AbsoluteDate.parseCCSDSUnsegmentedTimeCode((byte) 0x2F, (byte) 0x0, timeJ2000Epoch, AbsoluteDate.J2000_EPOCH);
542 Assertions.assertEquals(0, ccsds3.durationFrom(reference), lsb / 2);
543
544 }
545
546 @Test
547 public void testCCSDSUnsegmentedWithExtendedPreamble() {
548
549 AbsoluteDate reference = new AbsoluteDate("2095-03-03T22:02:45.789012345678901", utc);
550 int leap = (int) FastMath.rint(utc.offsetFromTAI(reference));
551 double lsb = FastMath.pow(2.0, -48);
552
553 byte extendedPreamble = (byte) -0x80;
554 byte identification = (byte) 0x10;
555 byte coarseLength1 = (byte) 0x0C;
556 byte fineLength1 = (byte) 0x03;
557 byte coarseLength2 = (byte) 0x20;
558 byte fineLength2 = (byte) 0x0C;
559 byte[] timeCCSDSEpoch = new byte[] {
560 0x01, 0x02, 0x03, 0x04, (byte)(0x05 - leap),
561 -0x37, -0x04, -0x4A, -0x74, -0x2C, -0x3C
562 };
563 byte preamble1 = (byte) (extendedPreamble | identification | coarseLength1 | fineLength1);
564 byte preamble2 = (byte) (coarseLength2 | fineLength2);
565 AbsoluteDate ccsds1 =
566 AbsoluteDate.parseCCSDSUnsegmentedTimeCode(preamble1, preamble2, timeCCSDSEpoch, null);
567 Assertions.assertEquals(0, ccsds1.durationFrom(reference), lsb / 2);
568
569 }
570
571 @Test
572 public void testCCSDSDaySegmented() {
573
574 AbsoluteDate reference = new AbsoluteDate("2002-05-23T12:34:56.789012345678", TimeScalesFactory.getUTC());
575 double lsb = 1.0e-13;
576 byte[] timeCCSDSEpoch = new byte[] { 0x3F, 0x55, 0x02, -0x4D, 0x2C, -0x6B, 0x00, -0x44, 0x61, 0x4E };
577
578 for (int preamble = 0x00; preamble < 0x100; ++preamble) {
579 if (preamble == 0x42) {
580
581 AbsoluteDate ccsds1 =
582 AbsoluteDate.parseCCSDSDaySegmentedTimeCode((byte) preamble, timeCCSDSEpoch, null);
583 Assertions.assertEquals(0, ccsds1.durationFrom(reference), lsb / 2);
584 } else {
585 try {
586 AbsoluteDate.parseCCSDSDaySegmentedTimeCode((byte) preamble, timeCCSDSEpoch, null);
587 Assertions.fail("an exception should have been thrown");
588 } catch (OrekitException iae) {
589
590 }
591
592 }
593 }
594
595
596 byte[] timeJ2000Epoch = new byte[] { 0x03, 0x69, 0x02, -0x4D, 0x2C, -0x6B, 0x00, -0x44, 0x61, 0x4E };
597 try {
598 AbsoluteDate.parseCCSDSDaySegmentedTimeCode((byte) 0x4A, timeJ2000Epoch, null);
599 Assertions.fail("an exception should have been thrown");
600 } catch (OrekitException iae) {
601
602 }
603
604
605 AbsoluteDate ccsds3 =
606 AbsoluteDate.parseCCSDSDaySegmentedTimeCode((byte) 0x4A, timeJ2000Epoch, DateComponents.J2000_EPOCH);
607 Assertions.assertEquals(0, ccsds3.durationFrom(reference), lsb / 2);
608
609
610 byte[] timeMicrosecond = new byte[] { 0x03, 0x69, 0x02, -0x4D, 0x2C, -0x6B, 0x00, 0x0C };
611 AbsoluteDate ccsds4 =
612 AbsoluteDate.parseCCSDSDaySegmentedTimeCode((byte) 0x49, timeMicrosecond, DateComponents.J2000_EPOCH);
613 Assertions.assertEquals(-0.345678e-6, ccsds4.durationFrom(reference), lsb / 2);
614
615 }
616
617 @Test
618 public void testCCSDSCalendarSegmented() {
619
620 AbsoluteDate reference = new AbsoluteDate("2002-05-23T12:34:56.789012345678", TimeScalesFactory.getUTC());
621 double lsb = 1.0e-13;
622
623
624 byte[] timeMonthDay = new byte[] { 0x07, -0x2E, 0x05, 0x17, 0x0C, 0x22, 0x38, 0x4E, 0x5A, 0x0C, 0x22, 0x38, 0x4E };
625 for (int preamble = 0x00; preamble < 0x100; ++preamble) {
626 if (preamble == 0x56) {
627 AbsoluteDate ccsds1 =
628 AbsoluteDate.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeMonthDay);
629 Assertions.assertEquals(0, ccsds1.durationFrom(reference), lsb / 2);
630 } else {
631 try {
632 AbsoluteDate.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeMonthDay);
633 Assertions.fail("an exception should have been thrown");
634 } catch (OrekitException iae) {
635
636 } catch (IllegalArgumentException iae) {
637
638
639 Assertions.assertEquals(preamble & 0x08, 0x08);
640 }
641
642 }
643 }
644
645
646 byte[] timeDay = new byte[] { 0x07, -0x2E, 0x00, -0x71, 0x0C, 0x22, 0x38, 0x4E, 0x5A, 0x0C, 0x22, 0x38, 0x4E };
647 for (int preamble = 0x00; preamble < 0x100; ++preamble) {
648 if (preamble == 0x5E) {
649 AbsoluteDate ccsds1 =
650 AbsoluteDate.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeDay);
651 Assertions.assertEquals(0, ccsds1.durationFrom(reference), lsb / 2);
652 } else {
653 try {
654 AbsoluteDate.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeDay);
655 Assertions.fail("an exception should have been thrown");
656 } catch (OrekitException iae) {
657
658 } catch (IllegalArgumentException iae) {
659
660
661 Assertions.assertEquals(preamble & 0x08, 0x00);
662 }
663
664 }
665 }
666
667
668 byte[] timeMicrosecond = new byte[] { 0x07, -0x2E, 0x00, -0x71, 0x0C, 0x22, 0x38, 0x4E, 0x5A, 0x0C };
669 AbsoluteDate ccsds4 =
670 AbsoluteDate.parseCCSDSCalendarSegmentedTimeCode((byte) 0x5B, timeMicrosecond);
671 Assertions.assertEquals(-0.345678e-6, ccsds4.durationFrom(reference), lsb / 2);
672
673 }
674
675 @Test
676 public void testExpandedConstructors() {
677 Assertions.assertThrows(IllegalArgumentException.class, () -> {
678 Assertions.assertEquals(new AbsoluteDate(new DateComponents(2002, 05, 28),
679 new TimeComponents(15, 30, 0),
680 TimeScalesFactory.getUTC()),
681 new AbsoluteDate(2002, 05, 28, 15, 30, 0, TimeScalesFactory.getUTC()));
682 Assertions.assertEquals(new AbsoluteDate(new DateComponents(2002, 05, 28), TimeComponents.H00,
683 TimeScalesFactory.getUTC()),
684 new AbsoluteDate(2002, 05, 28, TimeScalesFactory.getUTC()));
685 new AbsoluteDate(2002, 05, 28, 25, 30, 0, TimeScalesFactory.getUTC());
686 });
687 }
688
689 @Test
690 public void testHashcode() {
691 AbsoluteDate d1 =
692 new AbsoluteDate(new DateComponents(2006, 2, 25),
693 new TimeComponents(17, 10, 34),
694 utc);
695 AbsoluteDate d2 = new AbsoluteDate(new DateComponents(2006, 2, 25),
696 new TimeComponents(17, 10, 0),
697 utc).shiftedBy(34);
698 Assertions.assertEquals(d1.hashCode(), d2.hashCode());
699 Assertions.assertTrue(d1.hashCode() != d1.shiftedBy(1.0e-3).hashCode());
700 }
701
702 @Test
703 public void testInfinity() {
704 Assertions.assertTrue(AbsoluteDate.JULIAN_EPOCH.compareTo(AbsoluteDate.PAST_INFINITY) > 0);
705 Assertions.assertTrue(AbsoluteDate.JULIAN_EPOCH.compareTo(AbsoluteDate.FUTURE_INFINITY) < 0);
706 Assertions.assertTrue(AbsoluteDate.J2000_EPOCH.compareTo(AbsoluteDate.PAST_INFINITY) > 0);
707 Assertions.assertTrue(AbsoluteDate.J2000_EPOCH.compareTo(AbsoluteDate.FUTURE_INFINITY) < 0);
708 Assertions.assertTrue(AbsoluteDate.PAST_INFINITY.compareTo(AbsoluteDate.PAST_INFINITY) == 0);
709 Assertions.assertTrue(AbsoluteDate.PAST_INFINITY.compareTo(AbsoluteDate.JULIAN_EPOCH) < 0);
710 Assertions.assertTrue(AbsoluteDate.PAST_INFINITY.compareTo(AbsoluteDate.J2000_EPOCH) < 0);
711 Assertions.assertTrue(AbsoluteDate.PAST_INFINITY.compareTo(AbsoluteDate.FUTURE_INFINITY) < 0);
712 Assertions.assertTrue(AbsoluteDate.FUTURE_INFINITY.compareTo(AbsoluteDate.JULIAN_EPOCH) > 0);
713 Assertions.assertTrue(AbsoluteDate.FUTURE_INFINITY.compareTo(AbsoluteDate.J2000_EPOCH) > 0);
714 Assertions.assertTrue(AbsoluteDate.FUTURE_INFINITY.compareTo(AbsoluteDate.PAST_INFINITY) > 0);
715 Assertions.assertTrue(AbsoluteDate.FUTURE_INFINITY.compareTo(AbsoluteDate.FUTURE_INFINITY) == 0);
716 Assertions.assertTrue(Double.isInfinite(AbsoluteDate.FUTURE_INFINITY.durationFrom(AbsoluteDate.J2000_EPOCH)));
717 Assertions.assertTrue(Double.isInfinite(AbsoluteDate.FUTURE_INFINITY.durationFrom(AbsoluteDate.PAST_INFINITY)));
718 Assertions.assertTrue(Double.isInfinite(AbsoluteDate.PAST_INFINITY.durationFrom(AbsoluteDate.J2000_EPOCH)));
719 Assertions.assertTrue(Double.isNaN(AbsoluteDate.FUTURE_INFINITY.durationFrom(AbsoluteDate.FUTURE_INFINITY)));
720 Assertions.assertTrue(Double.isNaN(AbsoluteDate.PAST_INFINITY.durationFrom(AbsoluteDate.PAST_INFINITY)));
721 Assertions.assertEquals("5881610-07-11T23:59:59.999Z", AbsoluteDate.FUTURE_INFINITY.toString());
722 Assertions.assertEquals("-5877490-03-03T00:00:00.000Z", AbsoluteDate.PAST_INFINITY.toString());
723 Assertions.assertEquals(true, AbsoluteDate.FUTURE_INFINITY.equals(AbsoluteDate.FUTURE_INFINITY));
724 Assertions.assertEquals(true, AbsoluteDate.PAST_INFINITY.equals(AbsoluteDate.PAST_INFINITY));
725 Assertions.assertEquals(false, AbsoluteDate.PAST_INFINITY.equals(AbsoluteDate.FUTURE_INFINITY));
726 Assertions.assertEquals(false, AbsoluteDate.FUTURE_INFINITY.equals(AbsoluteDate.PAST_INFINITY));
727
728 Assertions.assertTrue(AbsoluteDate.J2000_EPOCH.durationFrom(AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(Double.NEGATIVE_INFINITY))
729 == Double.POSITIVE_INFINITY);
730 Assertions.assertTrue(AbsoluteDate.J2000_EPOCH.durationFrom(AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(Double.POSITIVE_INFINITY))
731 == Double.NEGATIVE_INFINITY);
732
733 }
734
735 @Test
736 public void testCompareTo() {
737
738 AbsoluteDate epoch =
739 new AbsoluteDate(2000, 1, 1, 12, 0, 0, TimeScalesFactory.getTAI());
740 Assertions.assertTrue(AbsoluteDate.JULIAN_EPOCH.compareTo(epoch) < 0);
741 Assertions.assertTrue(epoch.compareTo(AbsoluteDate.JULIAN_EPOCH) > 0);
742
743 AbsoluteDate d = epoch;
744 double epsilon = 1.0 - FastMath.nextDown(1.0);
745 Assertions.assertTrue(d.compareTo(d.shiftedBy(epsilon)) < 0);
746 Assertions.assertTrue(d.compareTo(d.shiftedBy(0)) == 0);
747 Assertions.assertTrue(d.compareTo(d.shiftedBy(-epsilon)) > 0);
748
749 d = epoch.shiftedBy(496891466)
750 .shiftedBy(0.7320114066633323)
751 .shiftedBy(-19730.732011406664);
752
753 AbsoluteDate d1 = epoch.shiftedBy(496891466 - 19730);
754 Assertions.assertTrue(d.compareTo(d1) < 0);
755
756 d1 = d1.shiftedBy(-1e-16);
757 Assertions.assertTrue(d.compareTo(d1) < 0,"" + d.durationFrom(d1));
758
759
760
761
762
763
764
765
766 }
767
768 @Test
769 public void testIsEqualTo() {
770 Assertions.assertTrue(present.isEqualTo(present));
771 Assertions.assertTrue(present.isEqualTo(presentToo));
772 Assertions.assertFalse(present.isEqualTo(past));
773 Assertions.assertFalse(present.isEqualTo(future));
774 }
775
776 @Test
777 public void testIsCloseTo() {
778 double tolerance = 10;
779 TimeStamped closeToPresent = new AnyTimeStamped(present.shiftedBy(5));
780 Assertions.assertTrue(present.isCloseTo(present, tolerance));
781 Assertions.assertTrue(present.isCloseTo(presentToo, tolerance));
782 Assertions.assertTrue(present.isCloseTo(closeToPresent, tolerance));
783 Assertions.assertFalse(present.isCloseTo(past, tolerance));
784 Assertions.assertFalse(present.isCloseTo(future, tolerance));
785 }
786
787 @Test
788 public void testIsBefore() {
789 Assertions.assertFalse(present.isBefore(past));
790 Assertions.assertFalse(present.isBefore(present));
791 Assertions.assertFalse(present.isBefore(presentToo));
792 Assertions.assertTrue(present.isBefore(future));
793 }
794
795 @Test
796 public void testIsAfter() {
797 Assertions.assertTrue(present.isAfter(past));
798 Assertions.assertFalse(present.isAfter(present));
799 Assertions.assertFalse(present.isAfter(presentToo));
800 Assertions.assertFalse(present.isAfter(future));
801 }
802
803 @Test
804 public void testIsBeforeOrEqualTo() {
805 Assertions.assertFalse(present.isBeforeOrEqualTo(past));
806 Assertions.assertTrue(present.isBeforeOrEqualTo(present));
807 Assertions.assertTrue(present.isBeforeOrEqualTo(presentToo));
808 Assertions.assertTrue(present.isBeforeOrEqualTo(future));
809 }
810
811 @Test
812 public void testIsAfterOrEqualTo() {
813 Assertions.assertTrue(present.isAfterOrEqualTo(past));
814 Assertions.assertTrue(present.isAfterOrEqualTo(present));
815 Assertions.assertTrue(present.isAfterOrEqualTo(presentToo));
816 Assertions.assertFalse(present.isAfterOrEqualTo(future));
817 }
818
819 @Test
820 public void testIsBetween() {
821 Assertions.assertTrue(present.isBetween(past, future));
822 Assertions.assertTrue(present.isBetween(future, past));
823 Assertions.assertFalse(past.getDate().isBetween(present, future));
824 Assertions.assertFalse(past.getDate().isBetween(future, present));
825 Assertions.assertFalse(future.getDate().isBetween(past, present));
826 Assertions.assertFalse(future.getDate().isBetween(present, past));
827 Assertions.assertFalse(present.isBetween(present, future));
828 Assertions.assertFalse(present.isBetween(past, present));
829 Assertions.assertFalse(present.isBetween(past, past));
830 Assertions.assertFalse(present.isBetween(present, present));
831 Assertions.assertFalse(present.isBetween(present, presentToo));
832 }
833
834 @Test
835 public void testIsBetweenOrEqualTo() {
836 Assertions.assertTrue(present.isBetweenOrEqualTo(past, future));
837 Assertions.assertTrue(present.isBetweenOrEqualTo(future, past));
838 Assertions.assertFalse(past.getDate().isBetweenOrEqualTo(present, future));
839 Assertions.assertFalse(past.getDate().isBetweenOrEqualTo(future, present));
840 Assertions.assertFalse(future.getDate().isBetweenOrEqualTo(past, present));
841 Assertions.assertFalse(future.getDate().isBetweenOrEqualTo(present, past));
842 Assertions.assertTrue(present.isBetweenOrEqualTo(present, future));
843 Assertions.assertTrue(present.isBetweenOrEqualTo(past, present));
844 Assertions.assertFalse(present.isBetweenOrEqualTo(past, past));
845 Assertions.assertTrue(present.isBetweenOrEqualTo(present, present));
846 Assertions.assertTrue(present.isBetweenOrEqualTo(present, presentToo));
847 }
848
849 @Test
850 public void testAccuracy() {
851 TimeScale tai = TimeScalesFactory.getTAI();
852 double sec = 0.281;
853 AbsoluteDate t = new AbsoluteDate(2010, 6, 21, 18, 42, sec, tai);
854 double recomputedSec = t.getComponents(tai).getTime().getSecond();
855 Assertions.assertEquals(sec, recomputedSec, FastMath.ulp(sec));
856 }
857
858 @Test
859 public void testIterationAccuracy() {
860
861 final TimeScale tai = TimeScalesFactory.getTAI();
862 final AbsoluteDate t0 = new AbsoluteDate(2010, 6, 21, 18, 42, 0.281, tai);
863
864
865
866 checkIteration(0.1, t0, 10000, 3.0, -1.19, 1.0e-4);
867
868
869
870 checkIteration(0.125, t0, 10000, 1.0e-15, 0.0, 1.0e-15);
871
872 }
873
874 private void checkIteration(final double step, final AbsoluteDate t0, final int nMax,
875 final double maxErrorFactor,
876 final double expectedMean, final double meanTolerance) {
877 final double epsilon = FastMath.ulp(step);
878 AbsoluteDate iteratedDate = t0;
879 double mean = 0;
880 for (int i = 1; i < nMax; ++i) {
881 iteratedDate = iteratedDate.shiftedBy(step);
882 AbsoluteDate directDate = t0.shiftedBy(i * step);
883 final double error = iteratedDate.durationFrom(directDate);
884 mean += error / (i * epsilon);
885 Assertions.assertEquals(0.0, iteratedDate.durationFrom(directDate), maxErrorFactor * i * epsilon);
886 }
887 mean /= nMax;
888 Assertions.assertEquals(expectedMean, mean, meanTolerance);
889 }
890
891 @Test
892 public void testIssue142() {
893
894 final AbsoluteDate epoch = AbsoluteDate.JAVA_EPOCH;
895 final TimeScale utc = TimeScalesFactory.getUTC();
896
897 Assertions.assertEquals("1970-01-01T00:00:00.000", epoch.toString(utc));
898 Assertions.assertEquals(0.0, epoch.durationFrom(new AbsoluteDate(1970, 1, 1, utc)), 1.0e-15);
899 Assertions.assertEquals(8.000082,
900 epoch.durationFrom(new AbsoluteDate(DateComponents.JAVA_EPOCH, TimeScalesFactory.getTAI())),
901 1.0e-15);
902
903
904 long msOffset = 1143849600000l;
905 final AbsoluteDate ad = new AbsoluteDate(epoch, msOffset/1000, TimeScalesFactory.getUTC());
906 Assertions.assertEquals("2006-04-01T00:00:00.000", ad.toString(utc));
907
908 }
909
910 @Test
911 public void testIssue148() {
912 final TimeScale utc = TimeScalesFactory.getUTC();
913 AbsoluteDate t0 = new AbsoluteDate(2012, 6, 30, 23, 59, 50.0, utc);
914 DateTimeComponents components = t0.shiftedBy(11.0 - 200 * Precision.EPSILON).getComponents(utc);
915 Assertions.assertEquals(2012, components.getDate().getYear());
916 Assertions.assertEquals( 6, components.getDate().getMonth());
917 Assertions.assertEquals( 30, components.getDate().getDay());
918 Assertions.assertEquals( 23, components.getTime().getHour());
919 Assertions.assertEquals( 59, components.getTime().getMinute());
920 Assertions.assertEquals( 61 - 200 * Precision.EPSILON,
921 components.getTime().getSecond(), 1.0e-15);
922 }
923
924 @Test
925 public void testIssue149() {
926 final TimeScale utc = TimeScalesFactory.getUTC();
927 AbsoluteDate t0 = new AbsoluteDate(2012, 6, 30, 23, 59, 59, utc);
928 DateTimeComponents components = t0.shiftedBy(1.0 - Precision.EPSILON).getComponents(utc);
929 Assertions.assertEquals(2012, components.getDate().getYear());
930 Assertions.assertEquals( 6, components.getDate().getMonth());
931 Assertions.assertEquals( 30, components.getDate().getDay());
932 Assertions.assertEquals( 23, components.getTime().getHour());
933 Assertions.assertEquals( 59, components.getTime().getMinute());
934 Assertions.assertEquals( 60 - Precision.EPSILON,
935 components.getTime().getSecond(), 1.0e-15);
936 }
937
938 @Test
939 public void testWrapAtMinuteEnd() {
940 TimeScale tai = TimeScalesFactory.getTAI();
941 TimeScale utc = TimeScalesFactory.getUTC();
942 AbsoluteDate date0 = new AbsoluteDate(DateComponents.J2000_EPOCH, TimeComponents.H12, tai);
943 AbsoluteDate ref = date0.shiftedBy(496891466.0).shiftedBy(0.7320114066633323);
944 AbsoluteDate date = ref.shiftedBy(33 * -597.9009700426262);
945 DateTimeComponents dtc = date.getComponents(utc);
946 Assertions.assertEquals(2015, dtc.getDate().getYear());
947 Assertions.assertEquals( 9, dtc.getDate().getMonth());
948 Assertions.assertEquals( 30, dtc.getDate().getDay());
949 Assertions.assertEquals( 7, dtc.getTime().getHour());
950 Assertions.assertEquals( 54, dtc.getTime().getMinute());
951 Assertions.assertEquals(60 - 9.094947e-13, dtc.getTime().getSecond(), 1.0e-15);
952 Assertions.assertEquals("2015-09-30T07:54:59.99999999999909",
953 date.toString(utc));
954 AbsoluteDate beforeMidnight = new AbsoluteDate(2008, 2, 29, 23, 59, 59.9994, utc);
955 AbsoluteDate stillBeforeMidnight = beforeMidnight.shiftedBy(2.0e-4);
956 Assertions.assertEquals(59.9994, beforeMidnight.getComponents(utc).getTime().getSecond(), 1.0e-15);
957 Assertions.assertEquals(59.9996, stillBeforeMidnight.getComponents(utc).getTime().getSecond(), 1.0e-15);
958 Assertions.assertEquals("2008-02-29T23:59:59.9994", beforeMidnight.toString(utc));
959 Assertions.assertEquals("2008-02-29T23:59:59.9996", stillBeforeMidnight.toString(utc));
960 }
961
962
963 @Test
964 public void testLastLeapOutput() {
965 UTCScale utc = TimeScalesFactory.getUTC();
966 AbsoluteDate t = utc.getLastKnownLeapSecond();
967 Assertions.assertEquals("23:59:59.500", t.shiftedBy(-0.5).toString(utc).substring(11));
968 Assertions.assertEquals("23:59:60.000", t.shiftedBy( 0.0).toString(utc).substring(11));
969 Assertions.assertEquals("23:59:60.500", t.shiftedBy(+0.5).toString(utc).substring(11));
970 }
971
972 @Test
973 public void testWrapBeforeLeap() {
974 UTCScale utc = TimeScalesFactory.getUTC();
975 AbsoluteDate t = new AbsoluteDate("2015-06-30T23:59:59.999999", utc);
976 Assertions.assertEquals(2015, t.getComponents(utc).getDate().getYear());
977 Assertions.assertEquals( 6, t.getComponents(utc).getDate().getMonth());
978 Assertions.assertEquals( 30, t.getComponents(utc).getDate().getDay());
979 Assertions.assertEquals( 23, t.getComponents(utc).getTime().getHour());
980 Assertions.assertEquals( 59, t.getComponents(utc).getTime().getMinute());
981 Assertions.assertEquals( 59.999999, t.getComponents(utc).getTime().getSecond(), 1.0e-6);
982 Assertions.assertEquals("2015-06-30T23:59:59.999999", t.toString(utc));
983 Assertions.assertEquals("2015-07-01T02:59:59.999999", t.toString(TimeScalesFactory.getGLONASS()));
984 }
985
986 @Test
987 public void testMjdInLeap() {
988
989 AbsoluteDate date1 = new AbsoluteDate(2008, 12, 31, 23, 59, 60.5, utc);
990
991
992 DateTimeComponents date1Components = date1.getComponents(utc);
993 int mjd = date1Components.getDate().getMJD();
994 double seconds = date1Components.getTime().getSecondsInUTCDay();
995 Assertions.assertEquals(54831, mjd);
996 Assertions.assertEquals(86400.5, seconds, 0);
997
998
999 AbsoluteDate date2 = AbsoluteDate.createMJDDate(mjd, seconds, utc);
1000 Assertions.assertEquals(date1, date2);
1001
1002
1003 try {
1004 AbsoluteDate.createMJDDate(mjd, seconds + 1.0, utc);
1005 Assertions.fail("an exception should have been thrown");
1006 } catch (OrekitIllegalArgumentException oiae) {
1007 Assertions.assertEquals(OrekitMessages.OUT_OF_RANGE_SECONDS_NUMBER_DETAIL, oiae.getSpecifier());
1008 Assertions.assertEquals(86400.5, (Double) oiae.getParts()[0], 0);
1009 Assertions.assertEquals(0, ((Number) oiae.getParts()[1]).doubleValue(), 0);
1010 Assertions.assertEquals(86400, ((Number) oiae.getParts()[2]).doubleValue(), 0);
1011 }
1012
1013 }
1014
1015 @Test
1016 public void testIssueTimesStampAccuracy() {
1017 String testString = "2019-02-01T13:06:03.115";
1018 TimeScale timeScale=TimeScalesFactory.getUTC();
1019
1020 DateTimeComponents expectedComponent = DateTimeComponents.parseDateTime(testString);
1021 AbsoluteDate expectedDate = new AbsoluteDate(expectedComponent, timeScale);
1022
1023 ZonedDateTime actualComponent = LocalDateTime.from(DateTimeFormatter.ISO_DATE_TIME.parse(testString)).atZone(ZoneOffset.UTC);
1024 AbsoluteDate actualDate = new AbsoluteDate(Timestamp.from(actualComponent.toInstant()), timeScale);
1025 Assertions.assertEquals(0.0, expectedDate.durationFrom(actualDate), 1.0e-15);
1026
1027 }
1028
1029 @Test
1030 public void testGetComponentsIssue681and676and694() {
1031
1032 AbsoluteDate date = new AbsoluteDate(2009, 1, 1, utc);
1033 double zeroUlp = FastMath.nextUp(0.0);
1034 double oneUlp = FastMath.ulp(1.0);
1035 double sixtyUlp = FastMath.ulp(60.0);
1036 double one = FastMath.nextDown(1.0);
1037 double sixty = FastMath.nextDown(60.0);
1038 double sixtyOne = FastMath.nextDown(61.0);
1039
1040
1041
1042
1043 check(date, 2009, 1, 1, 0, 0, 0, 1, 0, 0);
1044 check(date.shiftedBy(zeroUlp), 2009, 1, 1, 0, 0, zeroUlp, 0.5, 0, 0);
1045 check(date.shiftedBy(oneUlp), 2009, 1, 1, 0, 0, oneUlp, 0.5, 0, 0);
1046 check(date.shiftedBy(one), 2009, 1, 1, 0, 0, one, 0.5, 0, 0);
1047
1048 check(date.shiftedBy(59).shiftedBy(one), 2009, 1, 1, 0, 0, sixty, 1, 0, 0);
1049 check(date.shiftedBy(86399).shiftedBy(one), 2009, 1, 1, 23, 59, sixty, 1, 0, 0);
1050 check(date.shiftedBy(-zeroUlp), 2009, 1, 1, 0, 0, 0, 0.5, 0, 0);
1051 check(date.shiftedBy(-oneUlp), 2008, 12, 31, 23, 59, sixtyOne, 1, 0, 0);
1052 check(date.shiftedBy(-1).shiftedBy(zeroUlp), 2008, 12, 31, 23, 59, 60.0, 0.5, 0, 0);
1053 check(date.shiftedBy(-1).shiftedBy(-zeroUlp), 2008, 12, 31, 23, 59, 60.0, 0.5, 0, 0);
1054 check(date.shiftedBy(-1).shiftedBy(-oneUlp), 2008, 12, 31, 23, 59, 60.0, 0.5, 0, 0);
1055 check(date.shiftedBy(-1).shiftedBy(-sixtyUlp), 2008, 12, 31, 23, 59, sixty, 0.5, 0, 0);
1056 check(date.shiftedBy(-61).shiftedBy(zeroUlp), 2008, 12, 31, 23, 59, zeroUlp, 0.5, 0, 0);
1057 check(date.shiftedBy(-61).shiftedBy(oneUlp), 2008, 12, 31, 23, 59, oneUlp, 0.5, 0, 0);
1058
1059
1060
1061
1062 AbsoluteDate d = new AbsoluteDate(1966, 1, 1, utc);
1063 double ratePost = 0.0025920 / Constants.JULIAN_DAY;
1064 double factorPost = ratePost / (1 + ratePost);
1065 double ratePre = 0.0012960 / Constants.JULIAN_DAY;
1066 double factorPre = ratePre / (1 + ratePre);
1067 check(d, 1966, 1, 1, 0, 0, 0, 1, 0, 0);
1068 check(d.shiftedBy(zeroUlp), 1966, 1, 1, 0, 0, 0, 0.5, 0, 0);
1069 check(d.shiftedBy(oneUlp), 1966, 1, 1, 0, 0, oneUlp, 0.5, 0, 0);
1070 check(d.shiftedBy(one), 1966, 1, 1, 0, 0, one * (1 - factorPost), 0.5, 2, 0);
1071 check(d.shiftedBy(59).shiftedBy(one), 1966, 1, 1, 0, 0, sixty * (1 - factorPost), 1, 1, 0);
1072 check(d.shiftedBy(86399).shiftedBy(one), 1966, 1, 1, 23, 59, sixty - 86400 * factorPost, 1, 1, 0);
1073 check(d.shiftedBy(-zeroUlp), 1966, 1, 1, 0, 0, 0, 0.5, 0, 0);
1074
1075 check(d.shiftedBy(-oneUlp), 1965, 12, 31, 23, 59, 60.0, 1, 0, 0);
1076 check(d.shiftedBy(-1).shiftedBy(zeroUlp), 1965, 12, 31, 23, 59, 59 + factorPre, 0.5, 0, 0);
1077 check(d.shiftedBy(-1).shiftedBy(-zeroUlp), 1965, 12, 31, 23, 59, 59 + factorPre, 0.5, 0, 0);
1078 check(d.shiftedBy(-1).shiftedBy(-oneUlp), 1965, 12, 31, 23, 59, 59 + factorPre, 0.5, 0, 0);
1079 check(d.shiftedBy(-1).shiftedBy(-sixtyUlp), 1965, 12, 31, 23, 59, 59 + (1 + sixtyUlp) * factorPre, 0.5, 1, 0);
1080
1081 check(d.shiftedBy(-60).shiftedBy(zeroUlp), 1965, 12, 31, 23, 59, 60 * factorPre, 0, 0, sixtyUlp);
1082 check(d.shiftedBy(-60).shiftedBy(oneUlp), 1965, 12, 31, 23, 59, (oneUlp - oneUlp * factorPre) + 60 * factorPre, 0.5, 0, sixtyUlp);
1083
1084
1085 AbsoluteDate d2 = new AbsoluteDate(1972, 7, 1, utc);
1086 check(d2, 1972, 7, 1, 0, 0, 0, 1, 0, 0);
1087 check(d2.shiftedBy(zeroUlp), 1972, 7, 1, 0, 0, zeroUlp, 0.5, 0, 0);
1088 check(d2.shiftedBy(oneUlp), 1972, 7, 1, 0, 0, oneUlp, 0.5, 0, 0);
1089 check(d2.shiftedBy(one), 1972, 7, 1, 0, 0, one, 0.5, 0, 0);
1090 check(d2.shiftedBy(59).shiftedBy(one), 1972, 7, 1, 0, 0, sixty, 1, 0, 0);
1091 check(d2.shiftedBy(86399).shiftedBy(one), 1972, 7, 1, 23, 59, sixty, 1, 0, 0);
1092 check(d2.shiftedBy(-zeroUlp), 1972, 7, 1, 0, 0, 0, 0.5, 0, 0);
1093 check(d2.shiftedBy(-oneUlp), 1972, 6, 30, 23, 59, sixtyOne, 1, 0, 0);
1094 check(d2.shiftedBy(-1).shiftedBy(zeroUlp), 1972, 6, 30, 23, 59, 60.0, 0.5, 0, 0);
1095 check(d2.shiftedBy(-1).shiftedBy(-zeroUlp), 1972, 6, 30, 23, 59, 60.0, 0.5, 0, 0);
1096 check(d2.shiftedBy(-1).shiftedBy(-oneUlp), 1972, 6, 30, 23, 59, 60.0, 0.5, 0, 0);
1097 check(d2.shiftedBy(-1).shiftedBy(-sixtyUlp), 1972, 6, 30, 23, 59, sixty, 0.5, 0, 0);
1098 check(d2.shiftedBy(-61).shiftedBy(zeroUlp), 1972, 6, 30, 23, 59, zeroUlp, 0.5, 0, 0);
1099 check(d2.shiftedBy(-61).shiftedBy(oneUlp), 1972, 6, 30, 23, 59, oneUlp, 0.5, 0, 0);
1100
1101
1102 AbsoluteDate d3 = AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(-1230724800);
1103 check(d3, 1960, 12, 31, 23, 59, 60, 0.5, 0, 0);
1104 AbsoluteDate d4 = new AbsoluteDate(1961, 1, 1, utc);
1105 check(d4, 1961, 1, 1, 0, 0, 0, 0.5, 0, 0);
1106
1107
1108
1109
1110 DateTimeComponents actual = date.shiftedBy(Double.NaN).getComponents(utc);
1111 DateComponents dc = actual.getDate();
1112 TimeComponents tc = actual.getTime();
1113 MatcherAssert.assertThat(dc.getYear(), CoreMatchers.is(2009));
1114 MatcherAssert.assertThat(dc.getMonth(), CoreMatchers.is(1));
1115 MatcherAssert.assertThat(dc.getDay(), CoreMatchers.is(1));
1116 MatcherAssert.assertThat(tc.getHour(), CoreMatchers.is(0));
1117 MatcherAssert.assertThat(tc.getMinute(), CoreMatchers.is(0));
1118 MatcherAssert.assertThat("second", tc.getSecond(), CoreMatchers.is(Double.NaN));
1119 MatcherAssert.assertThat(tc.getMinutesFromUTC(), CoreMatchers.is(0));
1120 final double difference = new AbsoluteDate(actual, utc).durationFrom(date);
1121 MatcherAssert.assertThat(difference, CoreMatchers.is(Double.NaN));
1122 }
1123
1124 private void check(AbsoluteDate date,
1125 int year, int month, int day, int hour, int minute, double second,
1126 double roundTripUlps, final int secondUlps, final double absTol) {
1127 DateTimeComponents actual = date.getComponents(utc);
1128 DateComponents d = actual.getDate();
1129 TimeComponents t = actual.getTime();
1130 MatcherAssert.assertThat(d.getYear(), CoreMatchers.is(year));
1131 MatcherAssert.assertThat(d.getMonth(), CoreMatchers.is(month));
1132 MatcherAssert.assertThat(d.getDay(), CoreMatchers.is(day));
1133 MatcherAssert.assertThat(t.getHour(), CoreMatchers.is(hour));
1134 MatcherAssert.assertThat(t.getMinute(), CoreMatchers.is(minute));
1135 MatcherAssert.assertThat("second", t.getSecond(),
1136 OrekitMatchers.numberCloseTo(second, absTol, secondUlps));
1137 MatcherAssert.assertThat(t.getMinutesFromUTC(), CoreMatchers.is(0));
1138 final double tol = FastMath.ulp(second) * roundTripUlps;
1139 final double difference = new AbsoluteDate(actual, utc).durationFrom(date);
1140 MatcherAssert.assertThat(difference,
1141 OrekitMatchers.closeTo(0, FastMath.max(absTol, tol)));
1142 }
1143
1144
1145 @Test
1146 public void testToStringRfc3339() {
1147
1148 AbsoluteDate date = new AbsoluteDate(2009, 1, 1, utc);
1149 double one = FastMath.nextDown(1.0);
1150 double zeroUlp = FastMath.nextUp(0.0);
1151 double oneUlp = FastMath.ulp(1.0);
1152
1153 double sixtyUlp = FastMath.ulp(60.0);
1154
1155
1156
1157 check(date, "2009-01-01T00:00:00Z");
1158 check(date.shiftedBy(1), "2009-01-01T00:00:01Z");
1159
1160 check(date.shiftedBy(12.3456789123456789), "2009-01-01T00:00:12.34567891234568Z");
1161 check(date.shiftedBy(0.0123456789123456789), "2009-01-01T00:00:00.01234567891235Z");
1162
1163 check(date.shiftedBy(zeroUlp), "2009-01-01T00:00:00Z");
1164 check(date.shiftedBy(59.0).shiftedBy(one), "2009-01-01T00:00:59.99999999999999Z");
1165 check(date.shiftedBy(86399).shiftedBy(one), "2009-01-01T23:59:59.99999999999999Z");
1166 check(date.shiftedBy(oneUlp), "2009-01-01T00:00:00Z");
1167 check(date.shiftedBy(one), "2009-01-01T00:00:01Z");
1168 check(date.shiftedBy(-zeroUlp), "2009-01-01T00:00:00Z");
1169
1170 check(date.shiftedBy(-oneUlp), "2008-12-31T23:59:60.99999999999999Z");
1171 check(date.shiftedBy(-1).shiftedBy(one), "2008-12-31T23:59:60.99999999999999Z");
1172 check(date.shiftedBy(-0.5), "2008-12-31T23:59:60.5Z");
1173 check(date.shiftedBy(-1).shiftedBy(zeroUlp), "2008-12-31T23:59:60Z");
1174 check(date.shiftedBy(-1), "2008-12-31T23:59:60Z");
1175 check(date.shiftedBy(-1).shiftedBy(-zeroUlp), "2008-12-31T23:59:60Z");
1176 check(date.shiftedBy(-1).shiftedBy(-oneUlp), "2008-12-31T23:59:60Z");
1177 check(date.shiftedBy(-2), "2008-12-31T23:59:59Z");
1178 check(date.shiftedBy(-1).shiftedBy(-sixtyUlp), "2008-12-31T23:59:59.99999999999999Z");
1179 check(date.shiftedBy(-61).shiftedBy(zeroUlp), "2008-12-31T23:59:00Z");
1180 check(date.shiftedBy(-61).shiftedBy(oneUlp), "2008-12-31T23:59:00Z");
1181
1182
1183
1184
1185 final DecimalFormat format = new DecimalFormat("00.##############", new DecimalFormatSymbols(Locale.US));
1186 AbsoluteDate d = new AbsoluteDate(1966, 1, 1, utc);
1187 double ratePost = 0.0025920 / Constants.JULIAN_DAY;
1188 double factorPost = ratePost / (1 + ratePost);
1189 double ratePre = 0.0012960 / Constants.JULIAN_DAY;
1190 double factorPre = ratePre / (1 + ratePre);
1191 check(d, "1966-01-01T00:00:00Z");
1192 check(d.shiftedBy(zeroUlp), "1966-01-01T00:00:00Z");
1193 check(d.shiftedBy(oneUlp), "1966-01-01T00:00:00Z");
1194 check(d.shiftedBy(one), "1966-01-01T00:00:" + format.format( one * (1 - factorPost)) + "Z");
1195
1196 check(d.shiftedBy(59).shiftedBy(one), "1966-01-01T00:00:59.99999820000005Z");
1197
1198 check(d.shiftedBy(86399).shiftedBy(one), "1966-01-01T23:59:59.99740800007776Z");
1199 check(d.shiftedBy(-zeroUlp), "1966-01-01T00:00:00Z");
1200
1201 check(d.shiftedBy(-oneUlp), "1965-12-31T23:59:60Z");
1202 check(d.shiftedBy(-1).shiftedBy(zeroUlp), "1965-12-31T23:59:" + format.format( 59 + factorPre) + "Z");
1203 check(d.shiftedBy(-1).shiftedBy(-zeroUlp), "1965-12-31T23:59:" + format.format( 59 + factorPre) + "Z");
1204 check(d.shiftedBy(-1).shiftedBy(-oneUlp), "1965-12-31T23:59:" + format.format( 59 + factorPre) + "Z");
1205
1206 check(d.shiftedBy(-1).shiftedBy(-sixtyUlp), "1965-12-31T23:59:59.00000001499999Z");
1207
1208 check(d.shiftedBy(-60).shiftedBy(zeroUlp), "1965-12-31T23:59:" + format.format( 60 * factorPre) + "Z");
1209 check(d.shiftedBy(-60).shiftedBy(oneUlp), "1965-12-31T23:59:" + format.format( (oneUlp - oneUlp * factorPre) + 60 * factorPre) + "Z");
1210
1211
1212 check(new AbsoluteDate(1961, 1, 1, utc), "1961-01-01T00:00:00Z");
1213 AbsoluteDate d3 = AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(-1230724800);
1214 check(d3, "1960-12-31T23:59:60Z");
1215
1216
1217
1218
1219 check(new AbsoluteDate(123, 4, 5, 6, 7, 8.9, utc), "0123-04-05T06:07:08.9Z");
1220
1221
1222
1223
1224 check(new AbsoluteDate(-123, 4, 5, 6, 7, 8.9, utc), "-123-04-05T06:07:08.9Z");
1225 check(new AbsoluteDate(-1230, 4, 5, 6, 7, 8.9, utc), "-1230-04-05T06:07:08.9Z");
1226
1227 check(new AbsoluteDate(12300, 4, 5, 6, 7, 8.9, utc), "12300-04-05T06:07:08.9Z");
1228
1229 check(AbsoluteDate.FUTURE_INFINITY, "5881610-07-11T23:59:59.999Z");
1230 check(AbsoluteDate.PAST_INFINITY, "-5877490-03-03T00:00:00Z");
1231
1232 if ("1.8".equals(System.getProperty("java.specification.version"))) {
1233
1234
1235 check(date.shiftedBy(Double.NaN), "2009-01-01T00:00:\uFFFDZ");
1236 } else {
1237 check(date.shiftedBy(Double.NaN), "2009-01-01T00:00:NaNZ");
1238 }
1239 }
1240
1241 private void check(final AbsoluteDate d, final String s) {
1242 MatcherAssert.assertThat(d.toStringRfc3339(utc),
1243 CoreMatchers.is(s));
1244 MatcherAssert.assertThat(d.getComponents(utc).toStringRfc3339(),
1245 CoreMatchers.is(s));
1246 }
1247
1248
1249
1250 @Test
1251 public void testToString() {
1252
1253 AbsoluteDate date = new AbsoluteDate(2009, 1, 1, utc);
1254 double one = FastMath.nextDown(1.0);
1255 double zeroUlp = FastMath.nextUp(0.0);
1256 double oneUlp = FastMath.ulp(1.0);
1257
1258 double sixtyUlp = FastMath.ulp(60.0);
1259
1260
1261
1262 checkToString(date, "2009-01-01T00:00:00.000");
1263 checkToString(date.shiftedBy(1), "2009-01-01T00:00:01.000");
1264
1265 checkToString(date.shiftedBy(12.3456789123456789), "2009-01-01T00:00:12.34567891234568");
1266 checkToString(date.shiftedBy(0.0123456789123456789), "2009-01-01T00:00:00.01234567891235");
1267
1268 checkToString(date.shiftedBy(zeroUlp), "2009-01-01T00:00:00.000");
1269
1270 checkToString(date.shiftedBy(59.0).shiftedBy(one), "2009-01-01T00:00:59.99999999999999");
1271
1272 checkToString(date.shiftedBy(86399).shiftedBy(one), "2009-01-01T23:59:59.99999999999999");
1273 checkToString(date.shiftedBy(oneUlp), "2009-01-01T00:00:00.000");
1274 checkToString(date.shiftedBy(one), "2009-01-01T00:00:01.000");
1275 checkToString(date.shiftedBy(-zeroUlp), "2009-01-01T00:00:00.000");
1276
1277
1278 checkToString(date.shiftedBy(-oneUlp), "2008-12-31T23:59:60.99999999999999");
1279
1280 checkToString(date.shiftedBy(-1).shiftedBy(one), "2008-12-31T23:59:60.99999999999999");
1281 checkToString(date.shiftedBy(-0.5), "2008-12-31T23:59:60.500");
1282 checkToString(date.shiftedBy(-1).shiftedBy(zeroUlp), "2008-12-31T23:59:60.000");
1283 checkToString(date.shiftedBy(-1), "2008-12-31T23:59:60.000");
1284 checkToString(date.shiftedBy(-1).shiftedBy(-zeroUlp), "2008-12-31T23:59:60.000");
1285 checkToString(date.shiftedBy(-1).shiftedBy(-oneUlp), "2008-12-31T23:59:60.000");
1286 checkToString(date.shiftedBy(-2), "2008-12-31T23:59:59.000");
1287
1288 checkToString(date.shiftedBy(-1).shiftedBy(-sixtyUlp), "2008-12-31T23:59:59.99999999999999");
1289 checkToString(date.shiftedBy(-61).shiftedBy(zeroUlp), "2008-12-31T23:59:00.000");
1290 checkToString(date.shiftedBy(-61).shiftedBy(oneUlp), "2008-12-31T23:59:00.000");
1291
1292
1293
1294
1295 final DecimalFormat format = new DecimalFormat("00.##############", new DecimalFormatSymbols(Locale.US));
1296 AbsoluteDate d = new AbsoluteDate(1966, 1, 1, utc);
1297 double ratePost = 0.0025920 / Constants.JULIAN_DAY;
1298 double factorPost = ratePost / (1 + ratePost);
1299 double ratePre = 0.0012960 / Constants.JULIAN_DAY;
1300 double factorPre = ratePre / (1 + ratePre);
1301 checkToString(d, "1966-01-01T00:00:00.000");
1302 checkToString(d.shiftedBy(zeroUlp), "1966-01-01T00:00:00.000");
1303 checkToString(d.shiftedBy(oneUlp), "1966-01-01T00:00:00.000");
1304 checkToString(d.shiftedBy(one), "1966-01-01T00:00:" + format.format( one * (1 - factorPost)));
1305
1306 checkToString(d.shiftedBy(59).shiftedBy(one), "1966-01-01T00:00:" + format.format( 60 * (1 - factorPost)));
1307
1308 checkToString(d.shiftedBy(86399).shiftedBy(one), "1966-01-01T23:59:" + format.format( 60 - 86400 * factorPost));
1309 checkToString(d.shiftedBy(-zeroUlp), "1966-01-01T00:00:00.000");
1310
1311 checkToString(d.shiftedBy(-oneUlp), "1965-12-31T23:59:60.000");
1312 checkToString(d.shiftedBy(-1).shiftedBy(zeroUlp), "1965-12-31T23:59:" + format.format( 59 + factorPre) );
1313 checkToString(d.shiftedBy(-1).shiftedBy(-zeroUlp), "1965-12-31T23:59:" + format.format( 59 + factorPre) );
1314 checkToString(d.shiftedBy(-1).shiftedBy(-oneUlp), "1965-12-31T23:59:" + format.format( 59 + factorPre) );
1315
1316 checkToString(d.shiftedBy(-1).shiftedBy(-sixtyUlp), "1965-12-31T23:59:59.00000001499999");
1317
1318 checkToString(d.shiftedBy(-60).shiftedBy(zeroUlp), "1965-12-31T23:59:" + format.format( 60 * factorPre) );
1319 checkToString(d.shiftedBy(-60).shiftedBy(oneUlp), "1965-12-31T23:59:" + format.format( (oneUlp - oneUlp * factorPre) + 60 * factorPre) );
1320
1321
1322 checkToString(new AbsoluteDate(1961, 1, 1, utc), "1961-01-01T00:00:00.000");
1323 AbsoluteDate d3 = AbsoluteDate.ARBITRARY_EPOCH.shiftedBy(-1230724800);
1324 checkToString(d3, "1960-12-31T23:59:60.000");
1325
1326
1327
1328
1329 checkToString(new AbsoluteDate(123, 4, 5, 6, 7, 8.9, utc), "0123-04-05T06:07:08.900");
1330
1331
1332
1333
1334 checkToString(new AbsoluteDate(-123, 4, 5, 6, 7, 8.9, utc), "-123-04-05T06:07:08.900");
1335 checkToString(new AbsoluteDate(-1230, 4, 5, 6, 7, 8.9, utc), "-1230-04-05T06:07:08.900");
1336
1337 checkToString(new AbsoluteDate(12300, 4, 5, 6, 7, 8.9, utc), "12300-04-05T06:07:08.900");
1338
1339 checkToString(AbsoluteDate.FUTURE_INFINITY, "5881610-07-11T23:59:59.999");
1340 checkToString(AbsoluteDate.PAST_INFINITY, "-5877490-03-03T00:00:00.000");
1341
1342 if ("1.8".equals(System.getProperty("java.specification.version"))) {
1343
1344
1345 checkToString(date.shiftedBy(Double.NaN), "2009-01-01T00:00:\uFFFD");
1346 } else {
1347 checkToString(date.shiftedBy(Double.NaN), "2009-01-01T00:00:NaN");
1348 }
1349 }
1350
1351 private void checkToString(final AbsoluteDate d, final String s) {
1352 MatcherAssert.assertThat(d.toString(), CoreMatchers.is(s + "Z"));
1353 MatcherAssert.assertThat(d.getComponents(utc).toString(), CoreMatchers.is(s + "+00:00"));
1354 }
1355
1356 @Test
1357 public void testToStringWithoutUtcOffset() {
1358
1359 AbsoluteDate date = new AbsoluteDate(2009, 1, 1, utc);
1360 double one = FastMath.nextDown(1.0);
1361 double zeroUlp = FastMath.nextUp(0.0);
1362 double oneUlp = FastMath.ulp(1.0);
1363
1364 double sixtyUlp = FastMath.ulp(60.0);
1365
1366
1367
1368 checkToStringNoOffset(date, "2009-01-01T00:00:00.000");
1369 checkToStringNoOffset(date.shiftedBy(1), "2009-01-01T00:00:01.000");
1370
1371 checkToStringNoOffset(date.shiftedBy(12.3456789123456789), "2009-01-01T00:00:12.346");
1372 checkToStringNoOffset(date.shiftedBy(0.0123456789123456789), "2009-01-01T00:00:00.012");
1373
1374 checkToStringNoOffset(date.shiftedBy(zeroUlp), "2009-01-01T00:00:00.000");
1375
1376 checkToStringNoOffset(date.shiftedBy(59.0).shiftedBy(one), "2009-01-01T00:01:00.000");
1377
1378 checkToStringNoOffset(date.shiftedBy(86399).shiftedBy(one), "2009-01-02T00:00:00.000");
1379 checkToStringNoOffset(date.shiftedBy(oneUlp), "2009-01-01T00:00:00.000");
1380 checkToStringNoOffset(date.shiftedBy(one), "2009-01-01T00:00:01.000");
1381 checkToStringNoOffset(date.shiftedBy(-zeroUlp), "2009-01-01T00:00:00.000");
1382
1383
1384 checkToStringNoOffset(date.shiftedBy(-oneUlp), "2009-01-01T00:00:00.000");
1385
1386 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(one), "2009-01-01T00:00:00.000");
1387 checkToStringNoOffset(date.shiftedBy(-0.5), "2008-12-31T23:59:60.500");
1388 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(zeroUlp), "2008-12-31T23:59:60.000");
1389 checkToStringNoOffset(date.shiftedBy(-1), "2008-12-31T23:59:60.000");
1390 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(-zeroUlp), "2008-12-31T23:59:60.000");
1391 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(-oneUlp), "2008-12-31T23:59:60.000");
1392 checkToStringNoOffset(date.shiftedBy(-2), "2008-12-31T23:59:59.000");
1393
1394 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(-sixtyUlp), "2008-12-31T23:59:60.000");
1395 checkToStringNoOffset(date.shiftedBy(-61).shiftedBy(zeroUlp), "2008-12-31T23:59:00.000");
1396 checkToStringNoOffset(date.shiftedBy(-61).shiftedBy(oneUlp), "2008-12-31T23:59:00.000");
1397 }
1398
1399
1400 private void checkToStringNoOffset(final AbsoluteDate d, final String s) {
1401 MatcherAssert.assertThat(d.toStringWithoutUtcOffset(utc, 3), CoreMatchers.is(s));
1402 MatcherAssert.assertThat(
1403 d.getComponents(utc).toStringWithoutUtcOffset(utc.minuteDuration(d), 3),
1404 CoreMatchers.is(s));
1405 }
1406
1407
1408
1409
1410
1411 @Test
1412 public void testToStringException() {
1413 Utils.setDataRoot("no-data");
1414 try {
1415 DataContext.getDefault().getTimeScales().getUTC();
1416 Assertions.fail("Expected Exception");
1417 } catch (OrekitException e) {
1418
1419 Assertions.assertEquals(e.getSpecifier(), OrekitMessages.NO_IERS_UTC_TAI_HISTORY_DATA_LOADED);
1420 }
1421
1422 MatcherAssert.assertThat(present.toString(), CoreMatchers.is("2000-01-01T12:00:32.000 TAI"));
1423 MatcherAssert.assertThat(present.shiftedBy(Double.POSITIVE_INFINITY).toString(),
1424 CoreMatchers.is("5881610-07-11T23:59:59.999 TAI"));
1425 MatcherAssert.assertThat(present.shiftedBy(Double.NEGATIVE_INFINITY).toString(),
1426 CoreMatchers.is("-5877490-03-03T00:00:00.000 TAI"));
1427 String nan = "1.8".equals(System.getProperty("java.specification.version")) ? "\uFFFD" : "NaN";
1428 MatcherAssert.assertThat(present.shiftedBy(Double.NaN).toString(),
1429 CoreMatchers.is("2000-01-01T12:00:" + nan + " TAI"));
1430
1431
1432 AbsoluteDate d = present.shiftedBy(1e300).shiftedBy(1e300).shiftedBy(1e300);
1433 MatcherAssert.assertThat(d.toString(),
1434 CoreMatchers.is("(-9223372036854775779 + 3.0E300) seconds past epoch"));
1435 }
1436
1437
1438 @Test
1439 public void test_issue_943() {
1440
1441
1442 final AbsoluteDate date1 = new AbsoluteDate(AbsoluteDate.PAST_INFINITY, 0);
1443 final AbsoluteDate date2 = new AbsoluteDate(AbsoluteDate.PAST_INFINITY, 0);
1444 date1.durationFrom(date2);
1445 Assertions.assertEquals(date1, date2);
1446
1447
1448 final AbsoluteDate date3 = AbsoluteDate.PAST_INFINITY;
1449 final AbsoluteDate date4 = new AbsoluteDate(AbsoluteDate.PAST_INFINITY, 0);
1450 Assertions.assertEquals(date3, date4);
1451
1452
1453 final AbsoluteDate date5 = AbsoluteDate.FUTURE_INFINITY;
1454 final AbsoluteDate date6 = new AbsoluteDate(AbsoluteDate.FUTURE_INFINITY, 0);
1455 Assertions.assertEquals(date5, date6);
1456
1457
1458 final AbsoluteDate date7 = new AbsoluteDate(AbsoluteDate.PAST_INFINITY, 0);
1459 final AbsoluteDate date8 = new AbsoluteDate(AbsoluteDate.FUTURE_INFINITY, 0);
1460 Assertions.assertNotEquals(date7, date8);
1461
1462
1463 final AbsoluteDate date9 = new AbsoluteDate(AbsoluteDate.ARBITRARY_EPOCH.getEpoch(), Double.POSITIVE_INFINITY);
1464 final AbsoluteDate date10 = new AbsoluteDate(AbsoluteDate.ARBITRARY_EPOCH.getEpoch(), Double.POSITIVE_INFINITY);
1465 Assertions.assertEquals(date9, date10);
1466 }
1467
1468 public void testNegativeOffsetConstructor() {
1469 try {
1470 AbsoluteDate date = new AbsoluteDate(2019, 10, 11, 20, 40,
1471 FastMath.scalb(6629298651489277.0, -55),
1472 TimeScalesFactory.getTT());
1473 AbsoluteDate after = date.shiftedBy(Precision.EPSILON);
1474 Field epochField = AbsoluteDate.class.getDeclaredField("epoch");
1475 epochField.setAccessible(true);
1476 Field offsetField = AbsoluteDate.class.getDeclaredField("offset");
1477 offsetField.setAccessible(true);
1478 Assertions.assertEquals(624098367L, epochField.getLong(date));
1479 Assertions.assertEquals(FastMath.nextAfter(1.0, Double.NEGATIVE_INFINITY), offsetField.getDouble(date), 1.0e-20);
1480 Assertions.assertEquals(Precision.EPSILON, after.durationFrom(date), 1.0e-20);
1481 } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
1482 Assertions.fail(e.getLocalizedMessage());
1483 }
1484 }
1485
1486 @Test
1487 public void testNegativeOffsetShift() {
1488 try {
1489 AbsoluteDate reference = new AbsoluteDate(2019, 10, 11, 20, 40, 1.6667019180022178E-7,
1490 TimeScalesFactory.getTAI());
1491 double dt = FastMath.scalb(6596520010750484.0, -39);
1492 AbsoluteDate shifted = reference.shiftedBy(dt);
1493 AbsoluteDate after = shifted.shiftedBy(Precision.EPSILON);
1494 Field epochField = AbsoluteDate.class.getDeclaredField("epoch");
1495 epochField.setAccessible(true);
1496 Field offsetField = AbsoluteDate.class.getDeclaredField("offset");
1497 offsetField.setAccessible(true);
1498 Assertions.assertEquals(624110398L, epochField.getLong(shifted));
1499 Assertions.assertEquals(1.0 - 1.69267e-13, offsetField.getDouble(shifted), 1.0e-15);
1500 Assertions.assertEquals(Precision.EPSILON, after.durationFrom(shifted), 1.0e-20);
1501 } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
1502 Assertions.fail(e.getLocalizedMessage());
1503 }
1504 }
1505
1506 @Test
1507 public void testDurationFromWithTimeUnit() {
1508 AbsoluteDate reference = new AbsoluteDate(2023, 1, 1, 12, 13, 59.12334567, utc);
1509 for (TimeUnit timeUnit : TimeUnit.values()) {
1510 Assertions.assertEquals(0, reference.durationFrom(reference, timeUnit));
1511
1512 long dayInTimeUnit = timeUnit.convert((long) Constants.JULIAN_DAY, TimeUnit.SECONDS);
1513 for (int i = 1; i <= 365; i++) {
1514 AbsoluteDate minusDays = reference.shiftedBy(-i * Constants.JULIAN_DAY);
1515 AbsoluteDate plusDays = reference.shiftedBy(i* Constants.JULIAN_DAY);
1516
1517
1518 Assertions.assertEquals(i * dayInTimeUnit, reference.durationFrom(minusDays, timeUnit));
1519
1520 Assertions.assertEquals(-i * dayInTimeUnit, reference.durationFrom(plusDays, timeUnit));
1521 }
1522
1523 for (long ns = 1; ns <= 1_000_000_000; ns += 1_000_000) {
1524 AbsoluteDate minus = reference.shiftedBy(-1e-9 * ns);
1525 AbsoluteDate plus = reference.shiftedBy(1e-9 * ns);
1526
1527 double deltaInTimeUnit = ns / (double) timeUnit.toNanos(1);
1528 Assertions.assertEquals(FastMath.round(deltaInTimeUnit), reference.durationFrom(minus, timeUnit),
1529 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1530
1531 Assertions.assertEquals(FastMath.round(-deltaInTimeUnit), reference.durationFrom(plus, timeUnit),
1532 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1533 }
1534
1535
1536 }
1537 }
1538
1539 @Test
1540 public void testConstructWithTimeUnitOffset() {
1541 AbsoluteDate reference = new AbsoluteDate(2023, 1, 1, 12, 13, 59.12334567, utc);
1542
1543 for (TimeUnit timeUnit : TimeUnit.values()) {
1544 Assertions.assertEquals(0,
1545 FastMath.abs(reference.durationFrom(new AbsoluteDate(reference, 0, timeUnit))), 1e-10);
1546
1547 long dayInTimeUnit = timeUnit.convert((long) Constants.JULIAN_DAY, TimeUnit.SECONDS);
1548 for (int i = 1; i <= 365; i++) {
1549 AbsoluteDate minusDays = reference.shiftedBy(-i * Constants.JULIAN_DAY);
1550 AbsoluteDate plusDays = reference.shiftedBy(i* Constants.JULIAN_DAY);
1551
1552 Assertions.assertEquals(0,
1553 FastMath.abs(reference.durationFrom(new AbsoluteDate(minusDays, i * dayInTimeUnit, timeUnit))),
1554 1e-10,
1555 String.format("TimeUnit: %s", timeUnit));
1556 Assertions.assertEquals(0,
1557 FastMath.abs(reference.durationFrom(new AbsoluteDate(plusDays, -i * dayInTimeUnit, timeUnit))),
1558 1e-10,
1559 String.format("TimeUnit: %s", timeUnit));
1560 }
1561
1562 for (long ns = 1; ns <= 1_000_000_000; ns += 1_000_000) {
1563 if (timeUnit.convert(1, TimeUnit.SECONDS) < 1) {
1564
1565 continue;
1566 }
1567 AbsoluteDate minus = reference.shiftedBy(-1e-9 * ns);
1568 AbsoluteDate plus = reference.shiftedBy(1e-9 * ns);
1569
1570 double deltaInTimeUnit = ns / (double) timeUnit.toNanos(1);
1571 Assertions.assertEquals(0,
1572 FastMath.abs(reference.durationFrom(new AbsoluteDate(minus, FastMath.round(deltaInTimeUnit), timeUnit))),
1573 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1574 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1575 Assertions.assertEquals(0,
1576 FastMath.abs(reference.durationFrom(new AbsoluteDate(plus, FastMath.round(-deltaInTimeUnit), timeUnit))),
1577 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1578 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1579 }
1580 }
1581 }
1582
1583 @Test
1584 public void testShiftedByWithTimeUnit() {
1585 AbsoluteDate reference = new AbsoluteDate(2023, 1, 1, 12, 13, 59.12334567, utc);
1586
1587 for (TimeUnit timeUnit : TimeUnit.values()) {
1588 Assertions.assertEquals(0,
1589 FastMath.abs(reference.durationFrom(reference.shiftedBy( 0, timeUnit))), 1e-10);
1590
1591 long dayInTimeUnit = timeUnit.convert((long) Constants.JULIAN_DAY, TimeUnit.SECONDS);
1592 for (int i = 1; i <= 365; i++) {
1593 AbsoluteDate minusDays = reference.shiftedBy(-i * Constants.JULIAN_DAY);
1594 AbsoluteDate plusDays = reference.shiftedBy(i* Constants.JULIAN_DAY);
1595
1596 Assertions.assertEquals(0,
1597 FastMath.abs(reference.durationFrom(minusDays.shiftedBy(i * dayInTimeUnit, timeUnit))),
1598 1e-10,
1599 String.format("TimeUnit: %s", timeUnit));
1600 Assertions.assertEquals(0,
1601 FastMath.abs(reference.durationFrom(plusDays.shiftedBy(-i * dayInTimeUnit, timeUnit))),
1602 1e-10,
1603 String.format("TimeUnit: %s", timeUnit));
1604 }
1605
1606 for (long ns = 1; ns <= 1_000_000_000; ns += 1_000_000) {
1607 if (timeUnit.convert(1, TimeUnit.SECONDS) < 1) {
1608
1609 continue;
1610 }
1611 AbsoluteDate minus = reference.shiftedBy(-1e-9 * ns);
1612 AbsoluteDate plus = reference.shiftedBy(1e-9 * ns);
1613
1614 double deltaInTimeUnit = ns / (double) timeUnit.toNanos(1);
1615 Assertions.assertEquals(0,
1616 FastMath.abs(reference.durationFrom(minus.shiftedBy(FastMath.round(deltaInTimeUnit), timeUnit))),
1617 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1618 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1619 Assertions.assertEquals(0,
1620 FastMath.abs(reference.durationFrom(plus.shiftedBy(FastMath.round(-deltaInTimeUnit), timeUnit))),
1621 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1622 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1623 }
1624 }
1625 }
1626
1627 @Test
1628 public void testGetJulianDates() {
1629
1630 final TimeScale utc = TimeScalesFactory.getUTC();
1631
1632 AbsoluteDate reference = new AbsoluteDate(2024, 7, 4, 13, 0, 0, utc);
1633 AbsoluteDate referenceFromJDMethod = AbsoluteDate.createJDDate(2460496, .0416667 * Constants.JULIAN_DAY, utc);
1634 AbsoluteDate referenceFromMJDMethod = AbsoluteDate.createMJDDate(60495, 0.54166670 * Constants.JULIAN_DAY, utc);
1635
1636
1637 double mjdDateDefaultData = reference.getMJD();
1638 double jdDateDefaultData = reference.getJD();
1639 double mjdDate = reference.getMJD(utc);
1640 double jdDate = reference.getJD(utc);
1641
1642
1643
1644 Assertions.assertEquals(2460496.0416667, jdDateDefaultData, 1.0e-6);
1645 Assertions.assertEquals(60495.54166670, mjdDateDefaultData, 1.0e-6);
1646 Assertions.assertEquals(jdDate, jdDateDefaultData, 1.0e-6);
1647 Assertions.assertEquals(mjdDateDefaultData, mjdDate);
1648
1649
1650 Assertions.assertTrue(reference.isCloseTo(referenceFromJDMethod, 1e-2));
1651 Assertions.assertTrue(reference.isCloseTo(referenceFromMJDMethod, 1e-2));
1652 }
1653
1654
1655 @BeforeEach
1656 public void setUp() {
1657 Utils.setDataRoot("regular-data");
1658 utc = TimeScalesFactory.getUTC();
1659 present = new AbsoluteDate(new DateComponents(2000, 1, 1),
1660 new TimeComponents(12, 00, 00), utc);
1661 presentToo = new AnyTimeStamped(present.shiftedBy(0));
1662 past = new AnyTimeStamped(present.shiftedBy(-1000));
1663 future = new AnyTimeStamped(present.shiftedBy(1000));
1664 }
1665
1666 private TimeScale utc;
1667 private AbsoluteDate present;
1668 private AnyTimeStamped past;
1669 private AnyTimeStamped presentToo;
1670 private AnyTimeStamped future;
1671
1672 static class AnyTimeStamped implements TimeStamped {
1673 AbsoluteDate date;
1674 public AnyTimeStamped(AbsoluteDate date) {
1675 this.date = date;
1676 }
1677
1678 @Override
1679 public AbsoluteDate getDate() {
1680 return date;
1681 }
1682 }
1683 }