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.time.Instant;
20 import java.time.OffsetDateTime;
21 import java.time.format.DateTimeFormatter;
22 import java.util.Date;
23 import java.util.TimeZone;
24
25 import java.util.concurrent.TimeUnit;
26 import org.hamcrest.CoreMatchers;
27 import org.hamcrest.MatcherAssert;
28 import org.hipparchus.CalculusFieldElement;
29 import org.hipparchus.Field;
30 import org.hipparchus.analysis.differentiation.*;
31 import org.hipparchus.complex.Complex;
32 import org.hipparchus.complex.ComplexField;
33 import org.hipparchus.complex.FieldComplex;
34 import org.hipparchus.complex.FieldComplexField;
35 import org.hipparchus.dfp.Dfp;
36 import org.hipparchus.dfp.DfpField;
37 import org.hipparchus.util.Binary64;
38 import org.hipparchus.util.Binary64Field;
39 import org.hipparchus.util.FastMath;
40 import org.hipparchus.util.FieldTuple;
41 import org.hipparchus.util.Precision;
42 import org.hipparchus.util.Tuple;
43 import org.junit.jupiter.api.Assertions;
44 import org.junit.jupiter.api.BeforeEach;
45 import org.junit.jupiter.api.Test;
46 import org.orekit.OrekitMatchers;
47 import org.orekit.Utils;
48 import org.orekit.errors.OrekitException;
49 import org.orekit.errors.OrekitIllegalArgumentException;
50 import org.orekit.errors.OrekitMessages;
51 import org.orekit.utils.Constants;
52
53 class FieldAbsoluteDateTest {
54
55 private TimeScale utc;
56
57 @BeforeEach
58 public void setUp() {
59 Utils.setDataRoot("regular-data");
60 utc = TimeScalesFactory.getUTC();
61 }
62
63 @Test
64 void testStandardEpoch() {
65 doTestStandardEpoch(Binary64Field.getInstance());
66 }
67
68 @Test
69 void testStandardEpochStrings() {
70 doTestStandardEpochStrings(Binary64Field.getInstance());
71 }
72
73 @Test
74 void testJulianEpochRate() {
75 doTestJulianEpochRate(Binary64Field.getInstance());
76 }
77
78 @Test
79 void testBesselianEpochRate() {
80 doTestBesselianEpochRate(Binary64Field.getInstance());
81 }
82
83 @Test
84 void testLieske() {
85 doTestLieske(Binary64Field.getInstance());
86 }
87
88 @Test
89 void testParse() {
90 doTestParse(Binary64Field.getInstance());
91 }
92
93 @Test
94 void testLocalTimeParsing() {
95 doTestLocalTimeParsing(Binary64Field.getInstance());
96 }
97
98 @Test
99 void testTimeZoneDisplay() {
100 doTestTimeZoneDisplay(Binary64Field.getInstance());
101 }
102
103 @Test
104 void testLocalTimeLeapSecond() {
105 doTestLocalTimeLeapSecond(Binary64Field.getInstance());
106 }
107
108 @Test
109 void testTimeZoneLeapSecond() {
110 doTestTimeZoneLeapSecond(Binary64Field.getInstance());
111 }
112
113 @Test
114 void testParseLeap() {
115 doTestParseLeap(Binary64Field.getInstance());
116 }
117
118 @Test
119 void testOutput() {
120 doTestOutput(Binary64Field.getInstance());
121 }
122
123 @Test
124 void testJ2000() {
125 doTestJ2000(Binary64Field.getInstance());
126 }
127
128 @Test
129 void testFraction() {
130 doTestFraction(Binary64Field.getInstance());
131 }
132
133 @Test
134 void testScalesOffset() {
135 doTestScalesOffset(Binary64Field.getInstance());
136 }
137
138 @Test
139 void testUTC() {
140 doTestUTC(Binary64Field.getInstance());
141 }
142
143 @Test
144 void test1970() {
145 doTest1970(Binary64Field.getInstance());
146 }
147
148 @Test
149 void test1970Instant() {
150 doTest1970Instant(Binary64Field.getInstance());
151 }
152
153 @Test
154 void testInstantAccuracy() {
155 doTestInstantAccuracy(Binary64Field.getInstance());
156 }
157
158 @Test
159 void testToInstant() {
160 doTestToInstant(Binary64Field.getInstance());
161 }
162
163
164 @Test
165 void testUtcGpsOffset() {
166 doTestUtcGpsOffset(Binary64Field.getInstance());
167 }
168
169 @Test
170 void testGpsDate() {
171 doTestGpsDate(Binary64Field.getInstance());
172 }
173
174 @Test
175 void testMJDDate() {
176 doTestMJDDate(Binary64Field.getInstance());
177 }
178
179 @Test
180 void testJDDate() {
181 doTestJDDate(Binary64Field.getInstance());
182 }
183
184
185 @Test
186 void testIssue1310JDDateInTDB() {
187
188
189
190 final Field<Binary64> field = Binary64Field.getInstance();
191
192 final TDBScale TDBscale = TimeScalesFactory.getTDB();
193 final FieldAbsoluteDate<Binary64> refDate = new FieldAbsoluteDate<>(field,
194 new AbsoluteDate("2023-08-01T00:00:00.000", TDBscale));
195
196
197
198 final FieldAbsoluteDate<Binary64> wrongDate = FieldAbsoluteDate.createJDDate(2460157,
199 field.getOne().multiply(Constants.JULIAN_DAY / 2.0d), TDBscale);
200 final FieldAbsoluteDate<Binary64> properDate = FieldAbsoluteDate.createJDDate(2460157,
201 field.getOne().multiply(Constants.JULIAN_DAY / 2.0d), TDBscale, TimeScalesFactory.getTT());
202
203
204
205
206
207 Assertions.assertEquals(0.0, wrongDate.durationFrom(refDate).getReal(), 1.270e-05);
208
209
210 Assertions.assertEquals(0.0, properDate.durationFrom(refDate).getReal(), 2.132e-13);
211 }
212
213 @Test
214 void testOffsets() {
215 doTestOffsets(Binary64Field.getInstance());
216 }
217
218 @Test
219 void testBeforeAndAfterLeap() {
220 doTestBeforeAndAfterLeap(Binary64Field.getInstance());
221 }
222
223 @Test
224 void testSymmetry() {
225 doTestSymmetry(Binary64Field.getInstance());
226 }
227
228 @Test
229 void testEquals() {
230 doTestEquals(Binary64Field.getInstance());
231 }
232
233 @Test
234 void testEqualsAddendum() {
235
236 final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
237 final UnivariateDerivative1 derivative1 = new UnivariateDerivative1(0., 1);
238 final UnivariateDerivative1Field field = UnivariateDerivative1Field.getInstance();
239 final FieldAbsoluteDate<UnivariateDerivative1> fieldDate = new FieldAbsoluteDate<>(field,
240 date).shiftedBy(derivative1);
241 final FieldAbsoluteDate<UnivariateDerivative1> sameFieldDate = fieldDate.shiftedBy(0);
242
243 final boolean isEqual = fieldDate.equals(new FieldAbsoluteDate<>(field, date));
244
245 Assertions.assertFalse(isEqual);
246 Assertions.assertEquals(sameFieldDate.hashCode(), fieldDate.hashCode());
247 Assertions.assertEquals(sameFieldDate, fieldDate);
248 }
249
250 @Test
251 void testIsEqualTo() { doTestIsEqualTo(Binary64Field.getInstance()); }
252
253 @Test
254 void testIsCloseTo() { doTestIsCloseTo(Binary64Field.getInstance()); }
255
256 @Test
257 void testIsBefore() { doTestIsBefore(Binary64Field.getInstance()); }
258
259 @Test
260 void testIsAfter() { doTestIsAfter(Binary64Field.getInstance()); }
261
262 @Test
263 void testIsBeforeOrEqualTo() { doTestIsBeforeOrEqualTo(Binary64Field.getInstance()); }
264
265 @Test
266 void testIsAfterOrEqualTo() { doTestIsAfterOrEqualTo(Binary64Field.getInstance()); }
267
268 @Test
269 void testIsBetween() { doTestIsBetween(Binary64Field.getInstance()); }
270
271 @Test
272 void testIsBetweenOrEqualTo() { doTestIsBetweenOrEqualTo(Binary64Field.getInstance()); }
273
274 @Test
275 void testComponents() {
276 doTestComponents(Binary64Field.getInstance());
277 }
278
279 @Test
280 void testMonth() {
281 doTestMonth(Binary64Field.getInstance());
282 }
283
284 @Test
285 void testCCSDSUnsegmentedNoExtension() {
286 doTestCCSDSUnsegmentedNoExtension(Binary64Field.getInstance());
287 }
288
289 @Test
290 void testCCSDSUnsegmentedWithExtendedPreamble() {
291 doTestCCSDSUnsegmentedWithExtendedPreamble(Binary64Field.getInstance());
292 }
293
294 @Test
295 void testCCSDSDaySegmented() {
296 doTestCCSDSDaySegmented(Binary64Field.getInstance());
297 }
298
299 @Test
300 void testCCSDSCalendarSegmented() {
301 doTestCCSDSCalendarSegmented(Binary64Field.getInstance());
302 }
303
304 @Test
305 void testExpandedConstructors() {
306 doTestExpandedConstructors(Binary64Field.getInstance());
307 }
308
309 @Test
310 void testHashcode() {
311 doTestHashcode(Binary64Field.getInstance());
312 }
313
314 @Test
315 void testInfinity() {
316 doTestInfinity(Binary64Field.getInstance());
317 }
318
319 @Test
320 void testAccuracy() {
321 doTestAccuracy(Binary64Field.getInstance());
322 }
323
324 @Test
325 void testAccuracyIssue348() {
326 doTestAccuracyIssue348(Binary64Field.getInstance());
327 }
328
329 @Test
330 void testIterationAccuracy() {
331 doTestIterationAccuracy(Binary64Field.getInstance());
332 }
333
334 @Test
335 void testIssue142() {
336 doTestIssue142(Binary64Field.getInstance());
337 }
338
339 @Test
340 void testIssue148() {
341 doTestIssue148(Binary64Field.getInstance());
342 }
343
344 @Test
345 void testIssue149() {
346 doTestIssue149(Binary64Field.getInstance());
347 }
348
349 @Test
350 void testWrapAtMinuteEnd() {
351 doTestWrapAtMinuteEnd(Binary64Field.getInstance());
352 }
353
354 @Test
355 void testIssue508() {
356 doTestIssue508(Binary64Field.getInstance());
357 }
358
359 @Test
360 void testGetComponentsIssue681and676and694() {
361 doTestGetComponentsIssue681and676and694(Binary64Field.getInstance());
362 }
363
364 @Test
365 void testNegativeOffsetConstructor() {
366 doTestNegativeOffsetConstructor(Binary64Field.getInstance());
367 }
368
369 @Test
370 void testNegativeOffsetShift() {
371 doTestNegativeOffsetShift(Binary64Field.getInstance());
372 }
373
374 @Test
375 void testGetDayOfYear() {
376 doTestGetDayOfYear(Binary64Field.getInstance());
377 }
378
379 @Test
380 void testHasZeroField() {
381
382
383
384
385 final DSFactory dsFactory = new DSFactory(3, 2);
386 final Field<DerivativeStructure> dsField = dsFactory.getDerivativeField();
387
388
389 final FieldAbsoluteDate<DerivativeStructure> dsConstantDate = new FieldAbsoluteDate<>(dsField);
390 Assertions.assertTrue(dsConstantDate.hasZeroField());
391 Assertions.assertTrue(dsConstantDate.shiftedBy(dsField.getOne()).hasZeroField());
392
393
394 final DerivativeStructure dsDt0 = dsFactory.variable(0, 10.);
395 final DerivativeStructure dsDt1 = dsFactory.variable(1, -100.);
396 final DerivativeStructure dsDt2 = dsFactory.variable(2, 100.);
397 Assertions.assertFalse(dsConstantDate.shiftedBy(dsDt0).hasZeroField());
398 Assertions.assertFalse(dsConstantDate.shiftedBy(dsDt1).hasZeroField());
399 Assertions.assertFalse(dsConstantDate.shiftedBy(dsDt2).hasZeroField());
400 Assertions.assertFalse(dsConstantDate.shiftedBy(dsDt0).shiftedBy(dsDt1).shiftedBy(dsDt2).hasZeroField());
401
402
403
404
405 final Field<UnivariateDerivative1> u1Field = UnivariateDerivative1Field.getInstance();
406
407
408 final FieldAbsoluteDate<UnivariateDerivative1> u1ConstantDate = new FieldAbsoluteDate<>(u1Field);
409 Assertions.assertTrue(u1ConstantDate.hasZeroField());
410 Assertions.assertTrue(u1ConstantDate.shiftedBy(u1Field.getOne()).hasZeroField());
411 Assertions.assertTrue(u1ConstantDate.shiftedBy(new UnivariateDerivative1(10., 0.)).hasZeroField());
412
413
414 Assertions.assertFalse(u1ConstantDate.shiftedBy(new UnivariateDerivative1(10., 10.)).hasZeroField());
415
416
417
418
419 final Field<UnivariateDerivative2> u2Field = UnivariateDerivative2Field.getInstance();
420
421
422 final FieldAbsoluteDate<UnivariateDerivative2> u2ConstantDate = new FieldAbsoluteDate<>(u2Field);
423 Assertions.assertTrue(u2ConstantDate.hasZeroField());
424 Assertions.assertTrue(u2ConstantDate.shiftedBy(u2Field.getOne()).hasZeroField());
425 Assertions.assertTrue(u2ConstantDate.shiftedBy(new UnivariateDerivative2(10., 0., 0.)).hasZeroField());
426
427
428 Assertions.assertFalse(u2ConstantDate.shiftedBy(new UnivariateDerivative2(10., 1., 2.)).hasZeroField());
429
430
431
432
433 final Field<Gradient> gdField = GradientField.getField(2);
434
435
436 final FieldAbsoluteDate<Gradient> gdConstantDate = new FieldAbsoluteDate<>(gdField);
437 Assertions.assertTrue(gdConstantDate.hasZeroField());
438
439
440 final Gradient gdDt0 = Gradient.variable(2, 0, 10.);
441 final Gradient gdDt1 = Gradient.variable(2, 1, -100.);
442 Assertions.assertFalse(gdConstantDate.shiftedBy(gdDt0).hasZeroField());
443 Assertions.assertFalse(gdConstantDate.shiftedBy(gdDt1).hasZeroField());
444 Assertions.assertFalse(gdConstantDate.shiftedBy(gdDt0).shiftedBy(gdDt1).hasZeroField());
445
446
447 final FieldAbsoluteDate<SparseGradient> sgdDate = new FieldAbsoluteDate<>(SparseGradient.createConstant(10.).getField());
448 Assertions.assertTrue(sgdDate.hasZeroField());
449
450
451
452
453 final Field<Complex> cxField = ComplexField.getInstance();
454
455
456 final FieldAbsoluteDate<Complex> cxConstantDate = new FieldAbsoluteDate<>(cxField);
457 Assertions.assertTrue(cxConstantDate.hasZeroField());
458
459 Assertions.assertTrue(cxConstantDate.shiftedBy(new Complex(10., 0.)).hasZeroField());
460
461
462 Assertions.assertFalse(cxConstantDate.shiftedBy(new Complex(-100., 10.)).hasZeroField());
463
464
465 final Binary64Field b64Field = Binary64Field.getInstance();
466 final FieldAbsoluteDate<Binary64> b64Date = new FieldAbsoluteDate<>(b64Field);
467 Assertions.assertTrue(b64Date.hasZeroField());
468
469
470 final FieldAbsoluteDate<Dfp> dfpDate = new FieldAbsoluteDate<>(new DfpField(10));
471 Assertions.assertTrue(dfpDate.hasZeroField());
472
473
474 final FieldAbsoluteDate<FieldComplex<Complex>> fcxDate = new FieldAbsoluteDate<>(FieldComplexField.getField(cxField));
475 Assertions.assertTrue(fcxDate.hasZeroField());
476
477
478 final FieldAbsoluteDate<FieldTuple<DerivativeStructure>> ftpDate = new FieldAbsoluteDate<>(new FieldTuple<>(dsDt0, dsDt1).getField());
479 Assertions.assertTrue(ftpDate.hasZeroField());
480
481
482 final FieldAbsoluteDate<Tuple> tpDate = new FieldAbsoluteDate<>(new Tuple(0., 1.).getField());
483 Assertions.assertTrue(tpDate.hasZeroField());
484
485
486 final FDSFactory<Binary64> fdsFactory = new FDSFactory<>(b64Field, 3, 1);
487 final FieldAbsoluteDate<FieldDerivativeStructure<Binary64>> fdsDate = new FieldAbsoluteDate<>(fdsFactory.constant(1.).getField());
488 Assertions.assertTrue(fdsDate.hasZeroField());
489
490
491 final FieldAbsoluteDate<FieldGradient<Binary64>> fgdDate =
492 new FieldAbsoluteDate<>(new FieldGradient<>(fdsFactory.constant(1.)).getField());
493 Assertions.assertTrue(fgdDate.hasZeroField());
494
495
496 final FieldAbsoluteDate<FieldUnivariateDerivative1<Binary64>> fu1Date = new FieldAbsoluteDate<>(
497 FieldUnivariateDerivative1Field.getUnivariateDerivative1Field(Binary64Field.getInstance()));
498 Assertions.assertTrue(fu1Date.hasZeroField());
499
500
501 final FieldAbsoluteDate<FieldUnivariateDerivative2<Binary64>> fu2Date = new FieldAbsoluteDate<>(
502 FieldUnivariateDerivative2Field.getUnivariateDerivative2Field(Binary64Field.getInstance()));
503 Assertions.assertTrue(fu2Date.hasZeroField());
504 }
505
506 @Test
507 void testDurationFromWithTimeUnit() {
508 doTestDurationFromWithTimeUnit(Binary64Field.getInstance());
509 }
510
511 @Test
512 void testConstructWithTimeUnitOffset() {
513 doTestConstructWithTimeUnitOffset(Binary64Field.getInstance());
514 }
515
516 @Test
517 void testShiftedByWithTimeUnit() {
518 doTestShiftedByWithTimeUnit(Binary64Field.getInstance());
519 }
520
521 @Test
522 void testToStringWithoutUtcOffset() {
523 doTestToStringWithoutUtcOffset(Binary64Field.getInstance());
524 }
525
526
527 private <T extends CalculusFieldElement<T>> void doTestStandardEpoch(final Field<T> field) {
528
529 TimeScale tai = TimeScalesFactory.getTAI();
530 TimeScale tt = TimeScalesFactory.getTT();
531
532 FieldAbsoluteDate<T> JuEp = FieldAbsoluteDate.getJulianEpoch(field);
533 FieldAbsoluteDate<T> MJuEp = FieldAbsoluteDate.getModifiedJulianEpoch(field);
534 FieldAbsoluteDate<T> FiEp = FieldAbsoluteDate.getFiftiesEpoch(field);
535 FieldAbsoluteDate<T> CCSDS = FieldAbsoluteDate.getCCSDSEpoch(field);
536 FieldAbsoluteDate<T> GaEp = FieldAbsoluteDate.getGalileoEpoch(field);
537 FieldAbsoluteDate<T> GPSEp = FieldAbsoluteDate.getGPSEpoch(field);
538 FieldAbsoluteDate<T> JTTEP = FieldAbsoluteDate.getJ2000Epoch(field);
539
540 Assertions.assertEquals(-210866760000000L, JuEp.toDate(tt).getTime());
541 Assertions.assertEquals(-3506716800000L, MJuEp.toDate(tt).getTime());
542 Assertions.assertEquals(-631152000000L, FiEp.toDate(tt).getTime());
543 Assertions.assertEquals(-378691200000L, CCSDS.toDate(tai).getTime());
544 Assertions.assertEquals(935280019000L, GaEp.toDate(tai).getTime());
545 Assertions.assertEquals(315964819000L, GPSEp.toDate(tai).getTime());
546 Assertions.assertEquals(946728000000L, JTTEP.toDate(tt).getTime());
547
548 }
549
550 private <T extends CalculusFieldElement<T>> void doTestStandardEpochStrings(final Field<T> field) {
551
552 Assertions.assertEquals("-4712-01-01T12:00:00.000",
553 FieldAbsoluteDate.getJulianEpoch(field).toString(TimeScalesFactory.getTT()));
554 Assertions.assertEquals("1858-11-17T00:00:00.000",
555 FieldAbsoluteDate.getModifiedJulianEpoch(field).toString(TimeScalesFactory.getTT()));
556 Assertions.assertEquals("1950-01-01T00:00:00.000",
557 FieldAbsoluteDate.getFiftiesEpoch(field).toString(TimeScalesFactory.getTT()));
558 Assertions.assertEquals("1958-01-01T00:00:00.000",
559 FieldAbsoluteDate.getCCSDSEpoch(field).toString(TimeScalesFactory.getTAI()));
560 Assertions.assertEquals("1999-08-21T23:59:47.000",
561 FieldAbsoluteDate.getGalileoEpoch(field).toString(TimeScalesFactory.getUTC()));
562 Assertions.assertEquals("1980-01-06T00:00:00.000",
563 FieldAbsoluteDate.getGPSEpoch(field).toString(TimeScalesFactory.getUTC()));
564 Assertions.assertEquals("2000-01-01T12:00:00.000",
565 FieldAbsoluteDate.getJ2000Epoch(field).toString(TimeScalesFactory.getTT()));
566 Assertions.assertEquals("1970-01-01T00:00:00.000",
567 FieldAbsoluteDate.getJavaEpoch(field).toString(TimeScalesFactory.getUTC()));
568 }
569
570 private <T extends CalculusFieldElement<T>> void doTestJulianEpochRate(final Field<T> field) {
571
572 for (int i = 0; i < 10; ++i) {
573 FieldAbsoluteDate<T> j200i = FieldAbsoluteDate.createJulianEpoch(field.getZero().add(2000.0+i));
574 FieldAbsoluteDate<T> j2000 = FieldAbsoluteDate.getJ2000Epoch(field);
575 double expected = i * Constants.JULIAN_YEAR;
576 Assertions.assertEquals(expected, j200i.durationFrom(j2000).getReal(), 4.0e-15 * expected);
577 }
578
579 }
580
581 private <T extends CalculusFieldElement<T>> void doTestBesselianEpochRate(final Field<T> field) {
582
583 for (int i = 0; i < 10; ++i) {
584 FieldAbsoluteDate<T> b195i = FieldAbsoluteDate.createBesselianEpoch(field.getZero().add(1950.0 + i));
585 FieldAbsoluteDate<T> b1950 = FieldAbsoluteDate.createBesselianEpoch(field.getZero().add(1950.0));
586 double expected = i * Constants.BESSELIAN_YEAR;
587 Assertions.assertEquals(expected, b195i.durationFrom(b1950).getReal(), 4.0e-15 * expected);
588 }
589
590 }
591
592 private <T extends CalculusFieldElement<T>> void doTestLieske(final Field<T> field) {
593
594
595
596
597
598
599
600
601
602 final double publishedEpsilon = 1.0e-6 * Constants.JULIAN_YEAR;
603 checkEpochs(field, 1899.999142, 1900.000000, publishedEpsilon);
604 checkEpochs(field, 1900.000000, 1900.000858, publishedEpsilon);
605 checkEpochs(field, 1950.000000, 1949.999790, publishedEpsilon);
606 checkEpochs(field, 1950.000210, 1950.000000, publishedEpsilon);
607 checkEpochs(field, 2000.000000, 1999.998722, publishedEpsilon);
608 checkEpochs(field, 2000.001278, 2000.000000, publishedEpsilon);
609
610
611 final double accurateEpsilon = 1.2e-13 * Constants.JULIAN_YEAR;
612 checkEpochs(field, 1899.99914161068724704, 1900.00000000000000000, accurateEpsilon);
613 checkEpochs(field, 1900.00000000000000000, 1900.00085837097878165, accurateEpsilon);
614 checkEpochs(field, 1950.00000000000000000, 1949.99979044229979466, accurateEpsilon);
615 checkEpochs(field, 1950.00020956217615449, 1950.00000000000000000, accurateEpsilon);
616 checkEpochs(field, 2000.00000000000000000, 1999.99872251362080766, accurateEpsilon);
617 checkEpochs(field, 2000.00127751366506194, 2000.00000000000000000, accurateEpsilon);
618
619 }
620
621 private <T extends CalculusFieldElement<T>> void checkEpochs(final Field<T> field, final double besselianEpoch, final double julianEpoch, final double epsilon) {
622 final FieldAbsoluteDate<T> b = FieldAbsoluteDate.createBesselianEpoch(field.getZero().add(besselianEpoch));
623 final FieldAbsoluteDate<T> j = FieldAbsoluteDate.createJulianEpoch(field.getZero().add(julianEpoch));
624 Assertions.assertEquals(0.0, b.durationFrom(j).getReal(), epsilon);
625 }
626
627 private <T extends CalculusFieldElement<T>> void doTestParse(final Field<T> field) {
628
629 Assertions.assertEquals(FieldAbsoluteDate.getModifiedJulianEpoch(field),
630 new FieldAbsoluteDate<>(field, "1858-W46-3", TimeScalesFactory.getTT()));
631 Assertions.assertEquals(FieldAbsoluteDate.getJulianEpoch(field),
632 new FieldAbsoluteDate<>(field, "-4712-01-01T12:00:00.000", TimeScalesFactory.getTT()));
633 Assertions.assertEquals(FieldAbsoluteDate.getFiftiesEpoch(field),
634 new FieldAbsoluteDate<>(field, "1950-01-01", TimeScalesFactory.getTT()));
635 Assertions.assertEquals(FieldAbsoluteDate.getCCSDSEpoch(field),
636 new FieldAbsoluteDate<>(field, "1958-001", TimeScalesFactory.getTAI()));
637 }
638
639 private <T extends CalculusFieldElement<T>> void doTestLocalTimeParsing(final Field<T> field) {
640 TimeScale utc = TimeScalesFactory.getUTC();
641 Assertions.assertEquals(new FieldAbsoluteDate<>(field, "2011-12-31T23:00:00", utc),
642 new FieldAbsoluteDate<>(field, "2012-01-01T03:30:00+04:30", utc));
643 Assertions.assertEquals(new FieldAbsoluteDate<>(field, "2011-12-31T23:00:00", utc),
644 new FieldAbsoluteDate<>(field, "2012-01-01T03:30:00+0430", utc));
645 Assertions.assertEquals(new FieldAbsoluteDate<>(field, "2011-12-31T23:30:00", utc),
646 new FieldAbsoluteDate<>(field, "2012-01-01T03:30:00+04", utc));
647 Assertions.assertEquals(new FieldAbsoluteDate<>(field, "2012-01-01T05:17:00", utc),
648 new FieldAbsoluteDate<>(field, "2011-12-31T22:17:00-07:00", utc));
649 Assertions.assertEquals(new FieldAbsoluteDate<>(field, "2012-01-01T05:17:00", utc),
650 new FieldAbsoluteDate<>(field, "2011-12-31T22:17:00-0700", utc));
651 Assertions.assertEquals(new FieldAbsoluteDate<>(field, "2012-01-01T05:17:00", utc),
652 new FieldAbsoluteDate<>(field, "2011-12-31T22:17:00-07", utc));
653 }
654
655 private <T extends CalculusFieldElement<T>> void doTestTimeZoneDisplay(final Field<T> field) {
656 final TimeScale utc = TimeScalesFactory.getUTC();
657 final FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, "2000-01-01T01:01:01.000", utc);
658 Assertions.assertEquals("2000-01-01T01:01:01.000Z", date.toString());
659 Assertions.assertEquals("2000-01-01T11:01:01.000+10:00", date.toString( 600));
660 Assertions.assertEquals("1999-12-31T23:01:01.000-02:00", date.toString(-120));
661
662
663 final TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
664 Assertions.assertEquals("2001-01-22T11:30:00.000+01:00",
665 new FieldAbsoluteDate<>(field, "2001-01-22T10:30:00", utc).toString(tz));
666
667
668 Assertions.assertEquals("2001-06-23T11:30:00.000+02:00",
669 new FieldAbsoluteDate<>(field, "2001-06-23T09:30:00", utc).toString(tz));
670
671 }
672
673 private <T extends CalculusFieldElement<T>> void doTestLocalTimeLeapSecond(final Field<T> field) {
674
675 TimeScale utc = TimeScalesFactory.getUTC();
676 FieldAbsoluteDate<T> beforeLeap = new FieldAbsoluteDate<>(field, "2012-06-30T23:59:59.8", utc);
677 FieldAbsoluteDate<T> inLeap = new FieldAbsoluteDate<>(field, "2012-06-30T23:59:60.5", utc);
678 Assertions.assertEquals(0.7, inLeap.durationFrom(beforeLeap).getReal(), 1.0e-12);
679 for (int minutesFromUTC = -1500; minutesFromUTC < -1499; ++minutesFromUTC) {
680 DateTimeComponents dtcBeforeLeap = beforeLeap.getComponents(minutesFromUTC);
681 DateTimeComponents dtcInsideLeap = inLeap.getComponents(minutesFromUTC);
682
683
684 Assertions.assertEquals(dtcBeforeLeap.getDate(), dtcInsideLeap.getDate());
685
686 Assertions.assertEquals(dtcBeforeLeap.getTime().getHour(), dtcInsideLeap.getTime().getHour());
687 Assertions.assertEquals(dtcBeforeLeap.getTime().getMinute(), dtcInsideLeap.getTime().getMinute());
688 Assertions.assertEquals(minutesFromUTC, dtcBeforeLeap.getTime().getMinutesFromUTC());
689 Assertions.assertEquals(minutesFromUTC, dtcInsideLeap.getTime().getMinutesFromUTC());
690 Assertions.assertEquals(59.8, dtcBeforeLeap.getTime().getSecond(), 1.0e-10);
691 Assertions.assertEquals(60.5, dtcInsideLeap.getTime().getSecond(), 1.0e-10);
692 }
693
694 }
695
696 private <T extends CalculusFieldElement<T>> void doTestTimeZoneLeapSecond(final Field<T> field) {
697
698 TimeScale utc = TimeScalesFactory.getUTC();
699 final TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
700 FieldAbsoluteDate<T> localBeforeMidnight = new FieldAbsoluteDate<>(field, "2012-06-30T21:59:59.800", utc);
701 Assertions.assertEquals("2012-06-30T23:59:59.800+02:00",
702 localBeforeMidnight.toString(tz));
703 Assertions.assertEquals("2012-07-01T00:00:00.800+02:00",
704 localBeforeMidnight.shiftedBy(1.0).toString(tz));
705
706 FieldAbsoluteDate<T> beforeLeap = new FieldAbsoluteDate<>(field, "2012-06-30T23:59:59.8", utc);
707 FieldAbsoluteDate<T> inLeap = new FieldAbsoluteDate<>(field, "2012-06-30T23:59:60.5", utc);
708 Assertions.assertEquals(0.7, inLeap.durationFrom(beforeLeap).getReal(), 1.0e-12);
709 Assertions.assertEquals("2012-07-01T01:59:59.800+02:00", beforeLeap.toString(tz));
710 Assertions.assertEquals("2012-07-01T01:59:60.500+02:00", inLeap.toString(tz));
711
712 }
713
714 private <T extends CalculusFieldElement<T>> void doTestParseLeap(final Field<T> field) {
715 TimeScale utc = TimeScalesFactory.getUTC();
716 FieldAbsoluteDate<T> beforeLeap = new FieldAbsoluteDate<>(field, "2012-06-30T23:59:59.8", utc);
717 FieldAbsoluteDate<T> inLeap = new FieldAbsoluteDate<>(field, "2012-06-30T23:59:60.5", utc);
718 Assertions.assertEquals(0.7, inLeap.durationFrom(beforeLeap).getReal(), 1.0e-12);
719 Assertions.assertEquals("2012-06-30T23:59:60.500", inLeap.toString(utc));
720 }
721
722 private <T extends CalculusFieldElement<T>> void doTestOutput(final Field<T> field) {
723 TimeScale tt = TimeScalesFactory.getTT();
724 Assertions.assertEquals("1950-01-01T01:01:01.000",
725 FieldAbsoluteDate.getFiftiesEpoch(field).shiftedBy(3661.0).toString(tt));
726 Assertions.assertEquals("2000-01-01T13:01:01.000",
727 FieldAbsoluteDate.getJ2000Epoch(field).shiftedBy(3661.0).toString(tt));
728 }
729
730 private <T extends CalculusFieldElement<T>> void doTestJ2000(final Field<T> field) {
731 FieldAbsoluteDate<T> FAD = new FieldAbsoluteDate<>(field);
732 Assertions.assertEquals("2000-01-01T12:00:00.000",
733 FAD.toString(TimeScalesFactory.getTT()));
734 Assertions.assertEquals("2000-01-01T11:59:27.816",
735 FAD.toString(TimeScalesFactory.getTAI()));
736 Assertions.assertEquals("2000-01-01T11:58:55.816",
737 FAD.toString(utc));
738 Assertions.assertEquals("2000-01-01T12:00:00.000",
739 FieldAbsoluteDate.getJ2000Epoch(field).toString(TimeScalesFactory.getTT()));
740 Assertions.assertEquals("2000-01-01T11:59:27.816",
741 FieldAbsoluteDate.getJ2000Epoch(field).toString(TimeScalesFactory.getTAI()));
742 Assertions.assertEquals("2000-01-01T11:58:55.816",
743 FieldAbsoluteDate.getJ2000Epoch(field).toString(utc));
744 }
745
746 private <T extends CalculusFieldElement<T>> void doTestFraction(final Field<T> field) {
747 FieldAbsoluteDate<T> d =
748 new FieldAbsoluteDate<>(field, new DateComponents(2000, 1, 1), new TimeComponents(11, 59, 27.816),
749 TimeScalesFactory.getTAI());
750 Assertions.assertEquals(0, d.durationFrom(FieldAbsoluteDate.getJ2000Epoch(field)).getReal(), 1.0e-10);
751 }
752
753 private <T extends CalculusFieldElement<T>> void doTestScalesOffset(final Field<T> field) {
754 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2006, 2, 24),
755 new TimeComponents(15, 38, 0),
756 utc);
757 Assertions.assertEquals(33,
758 date.timeScalesOffset(TimeScalesFactory.getTAI(), utc).getReal(),
759 1.0e-10);
760 }
761
762 private <T extends CalculusFieldElement<T>> void doTestUTC(final Field<T> field) {
763 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new DateComponents(2002, 1, 1),
764 new TimeComponents(0, 0, 1),
765 utc);
766 Assertions.assertEquals("2002-01-01T00:00:01.000Z", date.toString());
767 }
768
769 private <T extends CalculusFieldElement<T>> void doTest1970(final Field<T> field) {
770 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, new Date(0L), utc);
771 Assertions.assertEquals("1970-01-01T00:00:00.000Z", date.toString());
772 }
773
774 private <T extends CalculusFieldElement<T>> void doTest1970Instant(final Field<T> field) {
775 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new FieldAbsoluteDate<>(field, Instant.EPOCH, utc).toString());
776 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new FieldAbsoluteDate<>(field, Instant.ofEpochMilli(0L), utc).toString());
777 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new FieldAbsoluteDate<>(field, Instant.EPOCH, (UTCScale) utc).toString());
778 Assertions.assertEquals("1970-01-01T00:00:00.000Z", new FieldAbsoluteDate<>(field, Instant.ofEpochMilli(0L), (UTCScale) utc).toString());
779 }
780
781 private <T extends CalculusFieldElement<T>> void doTestInstantAccuracy(final Field<T> field) {
782 Assertions.assertEquals("1970-01-02T00:16:40.123456789Z", new FieldAbsoluteDate<>(field, Instant.ofEpochSecond(87400, 123456789), utc).toString());
783 Assertions.assertEquals("1970-01-07T00:10:00.123456789Z", new FieldAbsoluteDate<>(field, Instant.ofEpochSecond(519000, 123456789), utc).toString());
784 Assertions.assertEquals("1970-01-02T00:16:40.123456789Z", new FieldAbsoluteDate<>(field, Instant.ofEpochSecond(87400, 123456789), (UTCScale) utc).toString());
785 Assertions.assertEquals("1970-01-07T00:10:00.123456789Z", new FieldAbsoluteDate<>(field, Instant.ofEpochSecond(519000, 123456789), (UTCScale) utc).toString());
786 }
787
788 public <T extends CalculusFieldElement<T>> void doTestToInstant(final Field<T> field) {
789 Assertions.assertEquals(Instant.ofEpochSecond(0), new FieldAbsoluteDate<>(field, "1970-01-01T00:00:00.000Z", utc).toInstant());
790 Assertions.assertEquals(Instant.ofEpochSecond(0), new FieldAbsoluteDate<>(field, "1970-01-01T00:00:00.000Z", utc).toInstant(TimeScalesFactory.getTimeScales()));
791
792 Instant expectedInstant = Instant.ofEpochSecond(519000, 123456789);
793 Assertions.assertEquals(expectedInstant, new FieldAbsoluteDate<>(field, "1970-01-07T00:10:00.123456789Z", utc).toInstant());
794 Assertions.assertEquals(expectedInstant, new FieldAbsoluteDate<>(field, "1970-01-07T00:10:00.123456789Z", utc).toInstant(TimeScalesFactory.getTimeScales()));
795
796 Assertions.assertEquals(OffsetDateTime.parse("2024-05-15T09:32:36.123456789Z", DateTimeFormatter.ISO_DATE_TIME).toInstant(),
797 new FieldAbsoluteDate<>(field,"2024-05-15T09:32:36.123456789Z", utc).toInstant());
798 Assertions.assertEquals(OffsetDateTime.parse("2024-05-15T09:32:36.123456789Z", DateTimeFormatter.ISO_DATE_TIME).toInstant(),
799 new FieldAbsoluteDate<>(field, "2024-05-15T09:32:36.123456789Z", utc).toInstant(TimeScalesFactory.getTimeScales()));
800
801 }
802
803 private <T extends CalculusFieldElement<T>> void doTestUtcGpsOffset(final Field<T> field) {
804 FieldAbsoluteDate<T> date1 = new FieldAbsoluteDate<>(field, new DateComponents(2005, 8, 9),
805 new TimeComponents(16, 31, 17),
806 utc);
807 FieldAbsoluteDate<T> date2 = new FieldAbsoluteDate<>(field, new DateComponents(2006, 8, 9),
808 new TimeComponents(16, 31, 17),
809 utc);
810 FieldAbsoluteDate<T> dateRef = new FieldAbsoluteDate<>(field, new DateComponents(1980, 1, 6),
811 TimeComponents.H00,
812 utc);
813
814
815 long noLeapGap = ((9347 * 24 + 16) * 60 + 31) * 60 + 17;
816 long realGap = (long) date1.durationFrom(dateRef).getReal();
817 Assertions.assertEquals(13L, realGap - noLeapGap);
818
819
820 noLeapGap = ((9712 * 24 + 16) * 60 + 31) * 60 + 17;
821 realGap = (long) date2.durationFrom(dateRef).getReal();
822 Assertions.assertEquals(14L, realGap - noLeapGap);
823
824 }
825
826 private <T extends CalculusFieldElement<T>> void doTestGpsDate(final Field<T> field) {
827 FieldAbsoluteDate<T> date = FieldAbsoluteDate.createGPSDate(1387, field.getZero().add(318677000.0));
828 FieldAbsoluteDate<T> ref = new FieldAbsoluteDate<>(field, new DateComponents(2006, 8, 9),
829 new TimeComponents(16, 31, 3),
830 utc);
831 Assertions.assertEquals(0, date.durationFrom(ref).getReal(), 1.0e-15);
832 }
833
834 private <T extends CalculusFieldElement<T>> void doTestMJDDate(final Field<T> field) {
835 FieldAbsoluteDate<T> dateA = FieldAbsoluteDate.createMJDDate(51544, field.getZero().add(0.5 * Constants.JULIAN_DAY),
836 TimeScalesFactory.getTT());
837 Assertions.assertEquals(0.0, FieldAbsoluteDate.getJ2000Epoch(field).durationFrom(dateA).getReal(), 1.0e-15);
838 FieldAbsoluteDate<T> dateB = FieldAbsoluteDate.createMJDDate(53774, field.getZero(), TimeScalesFactory.getUTC());
839 FieldAbsoluteDate<T> dateC = new FieldAbsoluteDate<>(field, "2006-02-08T00:00:00", TimeScalesFactory.getUTC());
840 Assertions.assertEquals(0.0, dateC.durationFrom(dateB).getReal(), 1.0e-15);
841 }
842
843 private <T extends CalculusFieldElement<T>> void doTestJDDate(final Field<T> field) {
844 final FieldAbsoluteDate<T> date = FieldAbsoluteDate.createJDDate(2400000, field.getZero().add(0.5 * Constants.JULIAN_DAY),
845 TimeScalesFactory.getTT());
846 Assertions.assertEquals(0.0, FieldAbsoluteDate.getModifiedJulianEpoch(field).durationFrom(date).getReal(), 1.0e-15);
847 }
848
849 private <T extends CalculusFieldElement<T>> void doTestOffsets(final Field<T> field) {
850 final TimeScale tai = TimeScalesFactory.getTAI();
851 FieldAbsoluteDate<T> leapStartUTC = new FieldAbsoluteDate<>(field, 1976, 12, 31, 23, 59, 59, utc);
852 FieldAbsoluteDate<T> leapEndUTC = new FieldAbsoluteDate<>(field, 1977, 1, 1, 0, 0, 0, utc);
853 FieldAbsoluteDate<T> leapStartTAI = new FieldAbsoluteDate<>(field, 1977, 1, 1, 0, 0, 14, tai);
854 FieldAbsoluteDate<T> leapEndTAI = new FieldAbsoluteDate<>(field, 1977, 1, 1, 0, 0, 16, tai);
855 Assertions.assertEquals(leapStartUTC, leapStartTAI);
856 Assertions.assertEquals(leapEndUTC, leapEndTAI);
857 Assertions.assertEquals(1, leapEndUTC.offsetFrom(leapStartUTC, utc).getReal(), 1.0e-10);
858 Assertions.assertEquals(1, leapEndTAI.offsetFrom(leapStartTAI, utc).getReal(), 1.0e-10);
859 Assertions.assertEquals(2, leapEndUTC.offsetFrom(leapStartUTC, tai).getReal(), 1.0e-10);
860 Assertions.assertEquals(2, leapEndTAI.offsetFrom(leapStartTAI, tai).getReal(), 1.0e-10);
861 Assertions.assertEquals(2, leapEndUTC.durationFrom(leapStartUTC).getReal(), 1.0e-10);
862 Assertions.assertEquals(2, leapEndTAI.durationFrom(leapStartTAI).getReal(), 1.0e-10);
863 }
864
865 private <T extends CalculusFieldElement<T>> void doTestBeforeAndAfterLeap(final Field<T> field) {
866 final TimeScale tai = TimeScalesFactory.getTAI();
867 FieldAbsoluteDate<T> leapStart = new FieldAbsoluteDate<>(field, 1977, 1, 1, 0, 0, 14, tai);
868 FieldAbsoluteDate<T> leapEnd = new FieldAbsoluteDate<>(field, 1977, 1, 1, 0, 0, 16, tai);
869 for (int i = -10; i < 10; ++i) {
870 final double dt = 1.1 * (2 * i - 1);
871 FieldAbsoluteDate<T> d1 = leapStart.shiftedBy(dt);
872 FieldAbsoluteDate<T> d2 = new FieldAbsoluteDate<>(leapStart, dt, tai);
873 FieldAbsoluteDate<T> d3 = new FieldAbsoluteDate<>(leapStart, dt, utc);
874 FieldAbsoluteDate<T> d4 = new FieldAbsoluteDate<>(leapEnd, dt, tai);
875 FieldAbsoluteDate<T> d5 = new FieldAbsoluteDate<>(leapEnd, dt, utc);
876 Assertions.assertTrue(FastMath.abs(d1.durationFrom(d2).getReal()) < 1.0e-10);
877 if (dt < 0) {
878 Assertions.assertTrue(FastMath.abs(d2.durationFrom(d3).getReal()) < 1.0e-10);
879 Assertions.assertTrue(d4.durationFrom(d5).getReal() > (1.0 - 1.0e-10));
880 } else {
881 Assertions.assertTrue(d2.durationFrom(d3).getReal() < (-1.0 + 1.0e-10));
882 Assertions.assertTrue(FastMath.abs(d4.durationFrom(d5).getReal()) < 1.0e-10);
883 }
884 }
885 }
886
887 private <T extends CalculusFieldElement<T>> void doTestSymmetry(final Field<T> field) {
888 final TimeScale tai = TimeScalesFactory.getTAI();
889 FieldAbsoluteDate<T> leapStart = new FieldAbsoluteDate<>(field, 1977, 1, 1, 0, 0, 14, tai);
890 for (int i = -10; i < 10; ++i) {
891 final double dt = 1.1 * (2 * i - 1);
892 Assertions.assertEquals(dt, new FieldAbsoluteDate<>(leapStart, dt, utc).offsetFrom(leapStart, utc).getReal(), 1.0e-10);
893 Assertions.assertEquals(dt, new FieldAbsoluteDate<>(leapStart, dt, tai).offsetFrom(leapStart, tai).getReal(), 1.0e-10);
894 Assertions.assertEquals(dt, leapStart.shiftedBy(dt).durationFrom(leapStart).getReal(), 1.0e-10);
895 }
896 }
897
898 private <T extends CalculusFieldElement<T>> void doTestEquals(final Field<T> field) {
899 FieldAbsoluteDate<T> d1 =
900 new FieldAbsoluteDate<>(field, new DateComponents(2006, 2, 25),
901 new TimeComponents(17, 10, 34),
902 utc);
903 FieldAbsoluteDate<T> d2 = new FieldAbsoluteDate<>(field, new DateComponents(2006, 2, 25),
904 new TimeComponents(17, 10, 0),
905 utc).shiftedBy(34);
906 Assertions.assertEquals(d1, d2);
907 Assertions.assertNotEquals(d1, this);
908 }
909
910 private <T extends CalculusFieldElement<T>> void doTestIsEqualTo(final Field<T> field) {
911 TestDates<T> dates = new TestDates<>(field);
912 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
913 Assertions.assertTrue(present.isEqualTo(dates.present));
914 Assertions.assertTrue(present.isEqualTo(dates.presentToo));
915 Assertions.assertFalse(present.isEqualTo(dates.past));
916 Assertions.assertFalse(present.isEqualTo(dates.future));
917 }
918
919 private <T extends CalculusFieldElement<T>> void doTestIsCloseTo(final Field<T> field) {
920 double tolerance = 10;
921 TestDates<T> dates = new TestDates<>(field);
922 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
923 FieldTimeStamped<T> closeToPresent = new AnyFieldTimeStamped<>(field, dates.presentDate.shiftedBy(5));
924 Assertions.assertTrue(present.isCloseTo(present, tolerance));
925 Assertions.assertTrue(present.isCloseTo(dates.presentToo, tolerance));
926 Assertions.assertTrue(present.isCloseTo(closeToPresent, tolerance));
927 Assertions.assertFalse(present.isCloseTo(dates.past, tolerance));
928 Assertions.assertFalse(present.isCloseTo(dates.future, tolerance));
929 }
930
931 private <T extends CalculusFieldElement<T>> void doTestIsBefore(final Field<T> field) {
932 TestDates<T> dates = new TestDates<>(field);
933 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
934 Assertions.assertFalse(present.isBefore(dates.past));
935 Assertions.assertFalse(present.isBefore(present));
936 Assertions.assertFalse(present.isBefore(dates.presentToo));
937 Assertions.assertTrue(present.isBefore(dates.future));
938 }
939
940 private <T extends CalculusFieldElement<T>> void doTestIsAfter(final Field<T> field) {
941 TestDates<T> dates = new TestDates<>(field);
942 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
943 Assertions.assertTrue(present.isAfter(dates.past));
944 Assertions.assertFalse(present.isAfter(present));
945 Assertions.assertFalse(present.isAfter(dates.presentToo));
946 Assertions.assertFalse(present.isAfter(dates.future));
947 }
948
949 private <T extends CalculusFieldElement<T>> void doTestIsBeforeOrEqualTo(final Field<T> field) {
950 TestDates<T> dates = new TestDates<>(field);
951 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
952 Assertions.assertFalse(present.isBeforeOrEqualTo(dates.past));
953 Assertions.assertTrue(present.isBeforeOrEqualTo(present));
954 Assertions.assertTrue(present.isBeforeOrEqualTo(dates.presentToo));
955 Assertions.assertTrue(present.isBeforeOrEqualTo(dates.future));
956 }
957
958 private <T extends CalculusFieldElement<T>> void doTestIsAfterOrEqualTo(final Field<T> field) {
959 TestDates<T> dates = new TestDates<>(field);
960 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
961 Assertions.assertTrue(present.isAfterOrEqualTo(dates.past));
962 Assertions.assertTrue(present.isAfterOrEqualTo(present));
963 Assertions.assertTrue(present.isAfterOrEqualTo(dates.presentToo));
964 Assertions.assertFalse(present.isAfterOrEqualTo(dates.future));
965 }
966
967 private <T extends CalculusFieldElement<T>> void doTestIsBetween(final Field<T> field) {
968 TestDates<T> dates = new TestDates<>(field);
969 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
970 Assertions.assertTrue(present.isBetween(dates.past, dates.future));
971 Assertions.assertTrue(present.isBetween(dates.future, dates.past));
972 Assertions.assertFalse(dates.past.getDate().isBetween(present, dates.future));
973 Assertions.assertFalse(dates.past.getDate().isBetween(dates.future, present));
974 Assertions.assertFalse(dates.future.getDate().isBetween(dates.past, present));
975 Assertions.assertFalse(dates.future.getDate().isBetween(present, dates.past));
976 Assertions.assertFalse(present.isBetween(present, dates.future));
977 Assertions.assertFalse(present.isBetween(dates.past, present));
978 Assertions.assertFalse(present.isBetween(dates.past, dates.past));
979 Assertions.assertFalse(present.isBetween(present, present));
980 Assertions.assertFalse(present.isBetween(present, dates.presentToo));
981 }
982
983 private <T extends CalculusFieldElement<T>> void doTestIsBetweenOrEqualTo(final Field<T> field) {
984 TestDates<T> dates = new TestDates<>(field);
985 FieldAbsoluteDate<T> present = dates.getPresentFieldAbsoluteDate();
986 Assertions.assertTrue(present.isBetweenOrEqualTo(dates.past, dates.future));
987 Assertions.assertTrue(present.isBetweenOrEqualTo(dates.future, dates.past));
988 Assertions.assertFalse(dates.past.getDate().isBetweenOrEqualTo(present, dates.future));
989 Assertions.assertFalse(dates.past.getDate().isBetweenOrEqualTo(dates.future, present));
990 Assertions.assertFalse(dates.future.getDate().isBetweenOrEqualTo(dates.past, present));
991 Assertions.assertFalse(dates.future.getDate().isBetweenOrEqualTo(present, dates.past));
992 Assertions.assertTrue(present.isBetweenOrEqualTo(present, dates.future));
993 Assertions.assertTrue(present.isBetweenOrEqualTo(dates.past, present));
994 Assertions.assertFalse(present.isBetweenOrEqualTo(dates.past, dates.past));
995 Assertions.assertTrue(present.isBetweenOrEqualTo(present, present));
996 Assertions.assertTrue(present.isBetweenOrEqualTo(present, dates.presentToo));
997 }
998
999 private <T extends CalculusFieldElement<T>> void doTestComponents(final Field<T> field) {
1000
1001
1002 DateComponents date = new DateComponents(2000, 1, 1);
1003 TimeComponents time = new TimeComponents(11, 59, 10);
1004 TimeScale[] scales = {
1005 TimeScalesFactory.getTAI(), TimeScalesFactory.getUTC(),
1006 TimeScalesFactory.getTT(), TimeScalesFactory.getTCG()
1007 };
1008 for (int i = 0; i < scales.length; ++i) {
1009 FieldAbsoluteDate<T> in = new FieldAbsoluteDate<>(field, date, time, scales[i]);
1010 for (int j = 0; j < scales.length; ++j) {
1011 DateTimeComponents pair = in.getComponents(scales[j]);
1012 if (i == j) {
1013 Assertions.assertEquals(date, pair.getDate());
1014 Assertions.assertEquals(time, pair.getTime());
1015 } else {
1016 Assertions.assertNotSame(date, pair.getDate());
1017 Assertions.assertNotSame(time, pair.getTime());
1018 }
1019 }
1020 }
1021 }
1022
1023 private <T extends CalculusFieldElement<T>> void doTestMonth(final Field<T> field) {
1024 TimeScale utc = TimeScalesFactory.getUTC();
1025 Assertions.assertEquals(new FieldAbsoluteDate<>(field, 2011, 2, 23, utc),
1026 new FieldAbsoluteDate<>(field, 2011, Month.FEBRUARY, 23, utc));
1027 Assertions.assertEquals(new FieldAbsoluteDate<>(field, 2011, 2, 23, 1, 2, 3.4, utc),
1028 new FieldAbsoluteDate<>(field, 2011, Month.FEBRUARY, 23, 1, 2, 3.4, utc));
1029 }
1030
1031 private <T extends CalculusFieldElement<T>> void doTestCCSDSUnsegmentedNoExtension(final Field<T> field) {
1032 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, "2002-05-23T12:34:56.789", utc);
1033 double lsb = FastMath.pow(2.0, -24);
1034
1035 byte[] timeCCSDSEpoch = new byte[] { 0x53, 0x7F, 0x40, -0x70, -0x37, -0x05, -0x19 };
1036 for (int preamble = 0x00; preamble < 0x80; ++preamble) {
1037 if (preamble == 0x1F) {
1038
1039 FieldAbsoluteDate<T> ccsds1 =
1040 FieldAbsoluteDate.parseCCSDSUnsegmentedTimeCode(field, (byte) preamble, (byte) 0x0, timeCCSDSEpoch, null);
1041 Assertions.assertEquals(0, ccsds1.durationFrom(reference).getReal(), lsb / 2);
1042 } else {
1043 try {
1044 FieldAbsoluteDate.parseCCSDSUnsegmentedTimeCode(field, (byte) preamble, (byte) 0x0, timeCCSDSEpoch, null);
1045 Assertions.fail("an exception should have been thrown");
1046 } catch (OrekitException iae) {
1047
1048 }
1049
1050 }
1051 }
1052
1053
1054 byte[] timeJ2000Epoch = new byte[] { 0x04, 0x7E, -0x0B, -0x10, -0x07, 0x16, -0x79 };
1055 try {
1056 FieldAbsoluteDate.parseCCSDSUnsegmentedTimeCode(field, (byte) 0x2F, (byte) 0x0, timeJ2000Epoch, null);
1057 Assertions.fail("an exception should have been thrown");
1058 } catch (OrekitException iae) {
1059
1060 }
1061
1062
1063 FieldAbsoluteDate<T> ccsds3 =
1064 FieldAbsoluteDate.parseCCSDSUnsegmentedTimeCode(field, (byte) 0x2F, (byte) 0x0, timeJ2000Epoch,
1065 FieldAbsoluteDate.getJ2000Epoch(field));
1066 Assertions.assertEquals(0, ccsds3.durationFrom(reference).getReal(), lsb / 2);
1067
1068 }
1069
1070 private <T extends CalculusFieldElement<T>> void doTestCCSDSUnsegmentedWithExtendedPreamble(final Field<T> field) {
1071
1072 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, "2095-03-03T22:02:45.789012345678901", utc);
1073 int leap = (int) FastMath.rint(utc.offsetFromTAI(reference.toAbsoluteDate()).toDouble());
1074
1075 byte extendedPreamble = (byte) -0x80;
1076 byte identification = (byte) 0x10;
1077 byte coarseLength1 = (byte) 0x0C;
1078 byte fineLength1 = (byte) 0x03;
1079 byte coarseLength2 = (byte) 0x20;
1080 byte fineLength2 = (byte) 0x10;
1081 byte[] timeCCSDSEpoch = new byte[] {
1082 0x01, 0x02, 0x03, 0x04, (byte)(0x05 - leap),
1083 -0x37, -0x04, -0x4A, -0x74, -0x2C, -0x3C, -0x48
1084 };
1085 byte preamble1 = (byte) (extendedPreamble | identification | coarseLength1 | fineLength1);
1086 byte preamble2 = (byte) (coarseLength2 | fineLength2);
1087 FieldAbsoluteDate<T> ccsds1 =
1088 FieldAbsoluteDate.parseCCSDSUnsegmentedTimeCode(field, preamble1, preamble2, timeCCSDSEpoch, null);
1089
1090
1091
1092 Assertions.assertEquals(-8.0e-18, ccsds1.durationFrom(reference).getReal(), 1.0e-18);
1093
1094 }
1095
1096 private <T extends CalculusFieldElement<T>> void doTestCCSDSDaySegmented(final Field<T> field) {
1097 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, "2002-05-23T12:34:56.789012345678", TimeScalesFactory.getUTC());
1098 double lsb = 1.0e-13;
1099 byte[] timeCCSDSEpoch = new byte[] { 0x3F, 0x55, 0x02, -0x4D, 0x2C, -0x6B, 0x00, -0x44, 0x61, 0x4E };
1100
1101 for (int preamble = 0x00; preamble < 0x100; ++preamble) {
1102 if (preamble == 0x42) {
1103
1104
1105 FieldAbsoluteDate<T> ccsds1 =
1106 FieldAbsoluteDate.parseCCSDSDaySegmentedTimeCode(field, (byte) preamble, timeCCSDSEpoch, null);
1107 Assertions.assertEquals(0, ccsds1.durationFrom(reference).getReal(), lsb / 2);
1108 } else {
1109 try {
1110 FieldAbsoluteDate.parseCCSDSDaySegmentedTimeCode(field, (byte) preamble, timeCCSDSEpoch, null);
1111 Assertions.fail("an exception should have been thrown");
1112 } catch (OrekitException iae) {
1113
1114 }
1115
1116 }
1117 }
1118
1119
1120 byte[] timeJ2000Epoch = new byte[] { 0x03, 0x69, 0x02, -0x4D, 0x2C, -0x6B, 0x00, -0x44, 0x61, 0x4E };
1121 try {
1122 FieldAbsoluteDate.parseCCSDSDaySegmentedTimeCode(field, (byte) 0x4A, timeJ2000Epoch, null);
1123 Assertions.fail("an exception should have been thrown");
1124 } catch (OrekitException iae) {
1125
1126 }
1127
1128
1129 FieldAbsoluteDate<T> ccsds3 =
1130 FieldAbsoluteDate.parseCCSDSDaySegmentedTimeCode(field, (byte) 0x4A, timeJ2000Epoch, DateComponents.J2000_EPOCH);
1131 Assertions.assertEquals(0, ccsds3.durationFrom(reference).getReal(), lsb / 2);
1132
1133
1134 byte[] timeMicrosecond = new byte[] { 0x03, 0x69, 0x02, -0x4D, 0x2C, -0x6B, 0x00, 0x0C };
1135 FieldAbsoluteDate<T> ccsds4 =
1136 FieldAbsoluteDate.parseCCSDSDaySegmentedTimeCode(field, (byte) 0x49, timeMicrosecond, DateComponents.J2000_EPOCH);
1137 Assertions.assertEquals(-0.345678e-6, ccsds4.durationFrom(reference).getReal(), lsb / 2);
1138
1139 }
1140
1141 private <T extends CalculusFieldElement<T>> void doTestCCSDSCalendarSegmented(final Field<T> field) {
1142
1143 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, "2002-05-23T12:34:56.789012345678", TimeScalesFactory.getUTC());
1144 double lsb = 1.0e-13;
1145 FieldAbsoluteDate<T> FAD = new FieldAbsoluteDate<>(field);
1146
1147 byte[] timeMonthDay = new byte[] { 0x07, -0x2E, 0x05, 0x17, 0x0C, 0x22, 0x38, 0x4E, 0x5A, 0x0C, 0x22, 0x38, 0x4E };
1148 for (int preamble = 0x00; preamble < 0x100; ++preamble) {
1149 if (preamble == 0x56) {
1150 FieldAbsoluteDate<T> ccsds1 =
1151 FAD.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeMonthDay);
1152 Assertions.assertEquals(0, ccsds1.durationFrom(reference).getReal(), lsb / 2);
1153 } else {
1154 try {
1155 FAD.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeMonthDay);
1156 Assertions.fail("an exception should have been thrown");
1157 } catch (OrekitException iae) {
1158
1159 } catch (IllegalArgumentException iae) {
1160
1161
1162 Assertions.assertEquals(preamble & 0x08, 0x08);
1163 }
1164
1165 }
1166 }
1167
1168
1169 byte[] timeDay = new byte[] { 0x07, -0x2E, 0x00, -0x71, 0x0C, 0x22, 0x38, 0x4E, 0x5A, 0x0C, 0x22, 0x38, 0x4E };
1170 for (int preamble = 0x00; preamble < 0x100; ++preamble) {
1171 if (preamble == 0x5E) {
1172 FieldAbsoluteDate<T> ccsds1 =
1173 FAD.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeDay);
1174 Assertions.assertEquals(0, ccsds1.durationFrom(reference).getReal(), lsb / 2);
1175 } else {
1176 try {
1177 FAD.parseCCSDSCalendarSegmentedTimeCode((byte) preamble, timeDay);
1178 Assertions.fail("an exception should have been thrown");
1179 } catch (OrekitException iae) {
1180
1181 } catch (IllegalArgumentException iae) {
1182
1183
1184 Assertions.assertEquals(preamble & 0x08, 0x00);
1185 }
1186
1187 }
1188 }
1189
1190
1191 byte[] timeMicrosecond = new byte[] { 0x07, -0x2E, 0x00, -0x71, 0x0C, 0x22, 0x38, 0x4E, 0x5A, 0x0C };
1192 FieldAbsoluteDate<T> ccsds4 =
1193 FAD.parseCCSDSCalendarSegmentedTimeCode((byte) 0x5B, timeMicrosecond);
1194 Assertions.assertEquals(-0.345678e-6, ccsds4.durationFrom(reference).getReal(), lsb / 2);
1195
1196 }
1197
1198 private <T extends CalculusFieldElement<T>> void doTestExpandedConstructors(final Field<T> field) {
1199 Assertions.assertEquals(new FieldAbsoluteDate<>(field, new DateComponents(2002, 5, 28),
1200 new TimeComponents(15, 30, 0),
1201 TimeScalesFactory.getUTC()),
1202 new FieldAbsoluteDate<>(field, 2002, 5, 28, 15, 30, 0, TimeScalesFactory.getUTC()));
1203 Assertions.assertEquals(new FieldAbsoluteDate<>(field, new DateComponents(2002, 5, 28), TimeComponents.H00,
1204 TimeScalesFactory.getUTC()),
1205 new FieldAbsoluteDate<>(field, 2002, 5, 28, TimeScalesFactory.getUTC()));
1206 try {
1207 new FieldAbsoluteDate<>(field, 2002, 5, 28, 25, 30, 0, TimeScalesFactory.getUTC());
1208 } catch (OrekitIllegalArgumentException oiae) {
1209 Assertions.assertEquals(OrekitMessages.NON_EXISTENT_HMS_TIME, oiae.getSpecifier());
1210 Assertions.assertEquals(25, ((Integer) oiae.getParts()[0]).intValue());
1211 Assertions.assertEquals(30, ((Integer) oiae.getParts()[1]).intValue());
1212 Assertions.assertEquals( 0, ((Double) oiae.getParts()[2]), 1.0e-15);
1213 }
1214 }
1215
1216 private <T extends CalculusFieldElement<T>> void doTestHashcode(final Field<T> field) {
1217 FieldAbsoluteDate<T> d1 =
1218 new FieldAbsoluteDate<>(field, new DateComponents(2006, 2, 25),
1219 new TimeComponents(17, 10, 34),
1220 utc);
1221 FieldAbsoluteDate<T> d2 = new FieldAbsoluteDate<>(field, new DateComponents(2006, 2, 25),
1222 new TimeComponents(17, 10, 0),
1223 utc).shiftedBy(34);
1224 Assertions.assertEquals(d1.hashCode(), d2.hashCode());
1225 Assertions.assertTrue(d1.hashCode() != d1.shiftedBy(1.0e-3).hashCode());
1226 }
1227
1228 private <T extends CalculusFieldElement<T>> void doTestInfinity(final Field<T> field) {
1229 Assertions.assertTrue(FieldAbsoluteDate.getJulianEpoch(field).compareTo(FieldAbsoluteDate.getPastInfinity(field)) > 0);
1230 Assertions.assertTrue(FieldAbsoluteDate.getJulianEpoch(field).compareTo(FieldAbsoluteDate.getFutureInfinity(field)) < 0);
1231 Assertions.assertTrue(FieldAbsoluteDate.getJ2000Epoch(field).compareTo(FieldAbsoluteDate.getPastInfinity(field)) > 0);
1232 Assertions.assertTrue(FieldAbsoluteDate.getJ2000Epoch(field).compareTo(FieldAbsoluteDate.getFutureInfinity(field)) < 0);
1233 Assertions.assertTrue(FieldAbsoluteDate.getPastInfinity(field).compareTo(FieldAbsoluteDate.getJulianEpoch(field)) < 0);
1234 Assertions.assertTrue(FieldAbsoluteDate.getPastInfinity(field).compareTo(FieldAbsoluteDate.getJ2000Epoch(field)) < 0);
1235 Assertions.assertTrue(FieldAbsoluteDate.getPastInfinity(field).compareTo(FieldAbsoluteDate.getFutureInfinity(field)) < 0);
1236 Assertions.assertTrue(FieldAbsoluteDate.getFutureInfinity(field).compareTo(FieldAbsoluteDate.getJulianEpoch(field)) > 0);
1237 Assertions.assertTrue(FieldAbsoluteDate.getFutureInfinity(field).compareTo(FieldAbsoluteDate.getJ2000Epoch(field)) > 0);
1238 Assertions.assertTrue(FieldAbsoluteDate.getFutureInfinity(field).compareTo(FieldAbsoluteDate.getPastInfinity(field)) > 0);
1239 Assertions.assertTrue(Double.isInfinite(FieldAbsoluteDate.getFutureInfinity(field).durationFrom(FieldAbsoluteDate.getJ2000Epoch(field)).getReal()));
1240 Assertions.assertTrue(Double.isInfinite(FieldAbsoluteDate.getFutureInfinity(field).durationFrom(FieldAbsoluteDate.getPastInfinity(field)).getReal()));
1241 Assertions.assertTrue(Double.isInfinite(FieldAbsoluteDate.getPastInfinity(field).durationFrom(FieldAbsoluteDate.getJ2000Epoch(field)).getReal()));
1242 Assertions.assertEquals("5881610-07-11T23:59:59.999Z", FieldAbsoluteDate.getFutureInfinity(field).toString());
1243 Assertions.assertEquals("-5877490-03-03T00:00:00.000Z", FieldAbsoluteDate.getPastInfinity(field).toString());
1244
1245 final FieldAbsoluteDate<T> j2000 = FieldAbsoluteDate.getJ2000Epoch(field);
1246 final FieldAbsoluteDate<T> arbitrary = FieldAbsoluteDate.getArbitraryEpoch(field);
1247 Assertions.assertEquals(Double.POSITIVE_INFINITY,
1248 j2000.durationFrom(arbitrary.shiftedBy(Double.NEGATIVE_INFINITY)).getReal());
1249 Assertions.assertEquals(Double.NEGATIVE_INFINITY,
1250 j2000.durationFrom(arbitrary.shiftedBy(Double.POSITIVE_INFINITY)).getReal());
1251 Assertions.assertEquals(Double.POSITIVE_INFINITY, j2000.durationFrom(arbitrary.shiftedBy(field.getZero().add(Double.NEGATIVE_INFINITY))).getReal());
1252 Assertions.assertEquals(Double.NEGATIVE_INFINITY,
1253 j2000.durationFrom(arbitrary.shiftedBy(field.getZero().add(Double.POSITIVE_INFINITY))).getReal());
1254
1255 }
1256
1257 private <T extends CalculusFieldElement<T>> void doTestAccuracy(final Field<T> field) {
1258 TimeScale tai = TimeScalesFactory.getTAI();
1259 double sec = 0.281;
1260 FieldAbsoluteDate<T> t = new FieldAbsoluteDate<>(field, 2010, 6, 21, 18, 42, sec, tai);
1261 double recomputedSec = t.getComponents(tai).getTime().getSecond();
1262 Assertions.assertEquals(sec, recomputedSec, FastMath.ulp(sec));
1263 }
1264
1265 private <T extends CalculusFieldElement<T>> void doTestAccuracyIssue348(final Field<T> field)
1266 {
1267 FieldAbsoluteDate<T> tF = new FieldAbsoluteDate<>(field,
1268 new DateComponents(1970, 1, 1),
1269 new TimeComponents(3, 25, 45.6789),
1270 TimeScalesFactory.getUTC());
1271 AbsoluteDate tA = tF.toAbsoluteDate();
1272 double delta = -0.01;
1273 T recomputedDelta = tF.shiftedBy(delta).durationFrom(tA);
1274 Assertions.assertEquals(delta, recomputedDelta.getReal(), 1.0e-17);
1275 }
1276
1277 private <T extends CalculusFieldElement<T>> void doTestIterationAccuracy(final Field<T> field) {
1278
1279 final TimeScale tai = TimeScalesFactory.getTAI();
1280 final FieldAbsoluteDate<T> t0 = new FieldAbsoluteDate<>(field, 2010, 6, 21, 18, 42, 0.281, tai);
1281
1282
1283
1284 checkIteration(0.1, t0, 10000, 3.0, -0.3874, 1.0e-4);
1285
1286
1287
1288 checkIteration(0.125, t0, 10000, 1.0e-15, 0.0, 1.0e-15);
1289 }
1290
1291 private <T extends CalculusFieldElement<T>> void checkIteration(final double step, final FieldAbsoluteDate<T> t0, final int nMax,
1292 final double maxErrorFactor,
1293 final double expectedMean, final double meanTolerance) {
1294 final double epsilon = FastMath.ulp(step);
1295 FieldAbsoluteDate<T> iteratedDate = t0;
1296 double mean = 0;
1297 for (int i = 1; i < nMax; ++i) {
1298 iteratedDate = iteratedDate.shiftedBy(step);
1299 FieldAbsoluteDate<T> directDate = t0.shiftedBy(i * step);
1300 final T error = iteratedDate.durationFrom(directDate);
1301 mean += error.getReal() / (i * epsilon);
1302 Assertions.assertEquals(0.0, iteratedDate.durationFrom(directDate).getReal(), maxErrorFactor * i * epsilon);
1303 }
1304 mean /= nMax;
1305 Assertions.assertEquals(expectedMean, mean, meanTolerance);
1306 }
1307
1308 private <T extends CalculusFieldElement<T>> void doTestIssue142(final Field<T> field) {
1309 final FieldAbsoluteDate<T> epoch = FieldAbsoluteDate.getJavaEpoch(field);
1310 final TimeScale utc = TimeScalesFactory.getUTC();
1311
1312 Assertions.assertEquals("1970-01-01T00:00:00.000", epoch.toString(utc));
1313 Assertions.assertEquals(0.0, epoch.durationFrom(new FieldAbsoluteDate<>(field, 1970, 1, 1, utc)).getReal(), 1.0e-15);
1314 Assertions.assertEquals(8.000082,
1315 epoch.durationFrom(new FieldAbsoluteDate<>(field, DateComponents.JAVA_EPOCH, TimeScalesFactory.getTAI())).getReal(),
1316 1.0e-15);
1317
1318
1319 long msOffset = 1143849600000L;
1320 final FieldAbsoluteDate<T> ad = new FieldAbsoluteDate<>(epoch, msOffset / 1000, TimeScalesFactory.getUTC());
1321 Assertions.assertEquals("2006-04-01T00:00:00.000", ad.toString(utc));
1322 }
1323
1324 private <T extends CalculusFieldElement<T>> void doTestIssue148(final Field<T> field) {
1325 final TimeScale utc = TimeScalesFactory.getUTC();
1326 FieldAbsoluteDate<T> t0 = new FieldAbsoluteDate<>(field, 2012, 6, 30, 23, 59, 50.0, utc);
1327 DateTimeComponents components = t0.shiftedBy(11.0 - 200 * Precision.EPSILON).getComponents(utc);
1328 Assertions.assertEquals(2012, components.getDate().getYear());
1329 Assertions.assertEquals( 6, components.getDate().getMonth());
1330 Assertions.assertEquals( 30, components.getDate().getDay());
1331 Assertions.assertEquals( 23, components.getTime().getHour());
1332 Assertions.assertEquals( 59, components.getTime().getMinute());
1333 Assertions.assertEquals( 61 - 200 * Precision.EPSILON,
1334 components.getTime().getSecond(), 1.0e-15);
1335 }
1336
1337 private <T extends CalculusFieldElement<T>> void doTestIssue149(final Field<T> field) {
1338 final TimeScale utc = TimeScalesFactory.getUTC();
1339 FieldAbsoluteDate<T> t0 = new FieldAbsoluteDate<>(field, 2012, 6, 30, 23, 59, 59, utc);
1340 DateTimeComponents components = t0.shiftedBy(1.0 - Precision.EPSILON).getComponents(utc);
1341 Assertions.assertEquals(2012, components.getDate().getYear());
1342 Assertions.assertEquals( 6, components.getDate().getMonth());
1343 Assertions.assertEquals( 30, components.getDate().getDay());
1344 Assertions.assertEquals( 23, components.getTime().getHour());
1345 Assertions.assertEquals( 59, components.getTime().getMinute());
1346 Assertions.assertEquals( 60 - Precision.EPSILON,
1347 components.getTime().getSecond(), 1.0e-15);
1348 }
1349
1350 private <T extends CalculusFieldElement<T>> void doTestWrapAtMinuteEnd(final Field<T> field) {
1351 TimeScale tai = TimeScalesFactory.getTAI();
1352 TimeScale utc = TimeScalesFactory.getUTC();
1353 FieldAbsoluteDate<T> date0 = new FieldAbsoluteDate<>(field, DateComponents.J2000_EPOCH, TimeComponents.H12, tai);
1354 FieldAbsoluteDate<T> ref = date0.shiftedBy(new TimeOffset(496891466L, 732011406663332300L));
1355 FieldAbsoluteDate<T> date = ref.shiftedBy(new TimeOffset(597L, 900970042626200000L).negate().multiply(33));
1356 DateTimeComponents dtc = date.getComponents(utc);
1357 Assertions.assertEquals( 2015, dtc.getDate().getYear());
1358 Assertions.assertEquals( 9, dtc.getDate().getMonth());
1359 Assertions.assertEquals( 30, dtc.getDate().getDay());
1360 Assertions.assertEquals( 7, dtc.getTime().getHour());
1361 Assertions.assertEquals( 54, dtc.getTime().getMinute());
1362 Assertions.assertEquals( 59L, dtc.getTime().getSplitSecond().getSeconds());
1363 Assertions.assertEquals( 999999999998732300L, dtc.getTime().getSplitSecond().getAttoSeconds());
1364 Assertions.assertEquals("2015-09-30T07:54:59.9999999999987323",
1365 date.toString(utc));
1366 FieldAbsoluteDate<T> beforeMidnight = new FieldAbsoluteDate<>(field, 2008, 2, 29, 23, 59,
1367 new TimeOffset(59L, 999400000000000000L), utc);
1368 FieldAbsoluteDate<T> stillBeforeMidnight = beforeMidnight.shiftedBy(2.0e-4);
1369 Assertions.assertEquals(59.9994, beforeMidnight.getComponents(utc).getTime().getSecond(), 1.0e-15);
1370 Assertions.assertEquals(59.9996, stillBeforeMidnight.getComponents(utc).getTime().getSecond(), 1.0e-15);
1371 Assertions.assertEquals("2008-02-29T23:59:59.9994", beforeMidnight.toString(utc));
1372 Assertions.assertEquals("2008-02-29T23:59:59.9996", stillBeforeMidnight.toString(utc));
1373 }
1374
1375 private <T extends CalculusFieldElement<T>> void doTestIssue508(final Field<T> field) {
1376 AbsoluteDate date = new AbsoluteDate(2000, 2, 24, 17, 5, 30.047, TimeScalesFactory.getUTC());
1377 FieldAbsoluteDate<T> tA = new FieldAbsoluteDate<>(field, date);
1378 FieldAbsoluteDate<T> tB = new FieldAbsoluteDate<>(date, field.getZero());
1379 Assertions.assertEquals(0.0, tA.durationFrom(tB).getReal(), Precision.SAFE_MIN);
1380 }
1381
1382 public <T extends CalculusFieldElement<T>> void doTestGetComponentsIssue681and676and694(
1383 final Field<T> field) {
1384
1385
1386 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field, 2009, 1, 1, utc);
1387 double attoSecond = 1.0e-18;
1388 double zeroUlp = FastMath.nextUp(0.0);
1389 double oneUlp = FastMath.ulp(1.0);
1390 double sixtyUlp = FastMath.ulp(60.0);
1391 double one = FastMath.nextDown(1.0);
1392 double sixty = FastMath.nextDown(60.0);
1393 double sixtyOne = FastMath.nextDown(61.0);
1394
1395
1396
1397
1398 check(date, 2009, 1, 1, 0, 0, 0, 1, 0, 0);
1399 check(date.shiftedBy(attoSecond), 2009, 1, 1, 0, 0, attoSecond, 0.5, 0, 0);
1400 check(date.shiftedBy(one), 2009, 1, 1, 0, 0, one, 0.5, 0, 0);
1401
1402 check(date.shiftedBy(59).shiftedBy(one), 2009, 1, 1, 0, 0, sixty, 1, 1, 0);
1403 check(date.shiftedBy(86399).shiftedBy(one), 2009, 1, 1, 23, 59, sixty, 1, 1, 0);
1404 check(date.shiftedBy(-zeroUlp), 2009, 1, 1, 0, 0, 0, 0.5, 0, 0);
1405 check(date.shiftedBy(-oneUlp), 2008, 12, 31, 23, 59, sixtyOne, 1, 1, 0);
1406 check(date.shiftedBy(-1).shiftedBy(zeroUlp), 2008, 12, 31, 23, 59, 60.0, 0.5, 0, 0);
1407 check(date.shiftedBy(-1).shiftedBy(-zeroUlp), 2008, 12, 31, 23, 59, 60.0, 0.5, 0, 0);
1408 check(date.shiftedBy(-1).shiftedBy(-oneUlp), 2008, 12, 31, 23, 59, 60.0, 0.5, 0, 0);
1409 check(date.shiftedBy(-1).shiftedBy(-sixtyUlp), 2008, 12, 31, 23, 59, sixty, 0.5, 0, 0);
1410 check(date.shiftedBy(-61).shiftedBy(attoSecond), 2008, 12, 31, 23, 59, attoSecond, 0.5, 0, 0);
1411
1412
1413
1414
1415 FieldAbsoluteDate<T> d = new FieldAbsoluteDate<>(field, 1966, 1, 1, utc);
1416 double ratePost = 0.0025920 / Constants.JULIAN_DAY;
1417 double factorPost = ratePost / (1 + ratePost);
1418 double ratePre = 0.0012960 / Constants.JULIAN_DAY;
1419 double factorPre = ratePre / (1 + ratePre);
1420 check(d, 1966, 1, 1, 0, 0, 0, 1, 0, 0);
1421 check(d.shiftedBy(zeroUlp), 1966, 1, 1, 0, 0, 0, 0.5, 0, 0);
1422 check(d.shiftedBy(attoSecond), 1966, 1, 1, 0, 0, attoSecond, 0.5, 0, 0);
1423 check(d.shiftedBy(one), 1966, 1, 1, 0, 0, one * (1 - factorPost), 1, 3, 0);
1424 check(d.shiftedBy(59).shiftedBy(one), 1966, 1, 1, 0, 0, sixty * (1 - factorPost), 1, 2, 0);
1425 check(d.shiftedBy(86399).shiftedBy(one), 1966, 1, 1, 23, 59, sixty - 86400 * factorPost, 1, 1, 0);
1426 check(d.shiftedBy(-zeroUlp), 1966, 1, 1, 0, 0, 0, 0.5, 0, 0);
1427
1428 check(d.shiftedBy(-oneUlp), 1965, 12, 31, 23, 59, 60.0, 1, 0, 0);
1429 check(d.shiftedBy(-1).shiftedBy(zeroUlp), 1965, 12, 31, 23, 59, 59 + factorPre, 0.5, 0, 0);
1430 check(d.shiftedBy(-1).shiftedBy(-zeroUlp), 1965, 12, 31, 23, 59, 59 + factorPre, 0.5, 0, 0);
1431 check(d.shiftedBy(-1).shiftedBy(-oneUlp), 1965, 12, 31, 23, 59, 59 + factorPre, 0.5, 0, 0);
1432 check(d.shiftedBy(-1).shiftedBy(-sixtyUlp), 1965, 12, 31, 23, 59, 59 + (1 + sixtyUlp) * factorPre, 0.5, 1, 0);
1433
1434 check(d.shiftedBy(-60).shiftedBy(zeroUlp), 1965, 12, 31, 23, 59, 60 * factorPre, 0, 0, sixtyUlp);
1435 check(d.shiftedBy(-60).shiftedBy(oneUlp), 1965, 12, 31, 23, 59, (oneUlp - oneUlp * factorPre) + 60 * factorPre, 0.5, 0, sixtyUlp);
1436
1437
1438 FieldAbsoluteDate<T> d2 = new FieldAbsoluteDate<>(field, 1972, 7, 1, utc);
1439 check(d2, 1972, 7, 1, 0, 0, 0, 1, 0, 0);
1440 check(d2.shiftedBy(attoSecond), 1972, 7, 1, 0, 0, attoSecond, 0.5, 0, 0);
1441 check(d2.shiftedBy(one), 1972, 7, 1, 0, 0, one, 0.5, 0, 0);
1442 check(d2.shiftedBy(59).shiftedBy(one), 1972, 7, 1, 0, 0, sixty, 1, 1, 0);
1443 check(d2.shiftedBy(86399).shiftedBy(one), 1972, 7, 1, 23, 59, sixty, 1, 1, 0);
1444 check(d2.shiftedBy(-zeroUlp), 1972, 7, 1, 0, 0, 0, 0.5, 0, 0);
1445 check(d2.shiftedBy(-oneUlp), 1972, 6, 30, 23, 59, sixtyOne, 1, 1, 0);
1446 check(d2.shiftedBy(-1).shiftedBy(zeroUlp), 1972, 6, 30, 23, 59, 60.0, 0.5, 0, 0);
1447 check(d2.shiftedBy(-1).shiftedBy(-zeroUlp), 1972, 6, 30, 23, 59, 60.0, 0.5, 0, 0);
1448 check(d2.shiftedBy(-1).shiftedBy(-oneUlp), 1972, 6, 30, 23, 59, 60.0, 0.5, 0, 0);
1449 check(d2.shiftedBy(-1).shiftedBy(-sixtyUlp), 1972, 6, 30, 23, 59, sixty, 0.5, 0, 0);
1450 check(d2.shiftedBy(-61).shiftedBy(attoSecond), 1972, 6, 30, 23, 59, attoSecond, 0.5, 0, 0);
1451
1452
1453 FieldAbsoluteDate<T> d3 = FieldAbsoluteDate.getArbitraryEpoch(field).shiftedBy(-1230724800);
1454 check(d3, 1960, 12, 31, 23, 59, 60, 0.5, 0, 0);
1455 FieldAbsoluteDate<T> d4 = new FieldAbsoluteDate<>(field, 1961, 1, 1, utc);
1456 check(d4, 1961, 1, 1, 0, 0, 0, 0.5, 0, 0);
1457
1458
1459
1460
1461 DateTimeComponents actual = date.shiftedBy(Double.NaN).getComponents(utc);
1462 DateComponents dc = actual.getDate();
1463 TimeComponents tc = actual.getTime();
1464 MatcherAssert.assertThat(dc.getYear(), CoreMatchers.is(2000));
1465 MatcherAssert.assertThat(dc.getMonth(), CoreMatchers.is(1));
1466 MatcherAssert.assertThat(dc.getDay(), CoreMatchers.is(1));
1467 MatcherAssert.assertThat(tc.getHour(), CoreMatchers.is(0));
1468 MatcherAssert.assertThat(tc.getMinute(), CoreMatchers.is(0));
1469 MatcherAssert.assertThat("second", tc.getSecond(), CoreMatchers.is(Double.NaN));
1470 MatcherAssert.assertThat(tc.getMinutesFromUTC(), CoreMatchers.is(0));
1471 final double difference = new FieldAbsoluteDate<>(field, actual, utc).durationFrom(date).getReal();
1472 MatcherAssert.assertThat(difference, CoreMatchers.is(Double.NaN));
1473 }
1474
1475 private <T extends CalculusFieldElement<T>> void doTestNegativeOffsetConstructor(final Field<T> field) {
1476 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field,
1477 2019, 10, 11, 20, 40,
1478 FastMath.scalb(6629298651489277.0, -55),
1479 TimeScalesFactory.getTT());
1480 FieldAbsoluteDate<T> after = date.shiftedBy(Precision.EPSILON);
1481 Assertions.assertEquals(624098367L, date.toAbsoluteDate().getSeconds());
1482 Assertions.assertEquals(FastMath.nextAfter(1.0, Double.NEGATIVE_INFINITY),
1483 1.0e-18 * date.toAbsoluteDate().getAttoSeconds(), 2.4e-15);
1484 Assertions.assertEquals(Precision.EPSILON, after.durationFrom(date).getReal(), 1.0e-18);
1485 }
1486
1487 private <T extends CalculusFieldElement<T>> void doTestNegativeOffsetShift(final Field<T> field) {
1488 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, 2019, 10, 11, 20, 40, 1.6667019180022178E-7,
1489 TimeScalesFactory.getTAI());
1490 T dt = field.getZero().newInstance(FastMath.scalb(6596520010750484.0, -39));
1491 FieldAbsoluteDate<T> shifted = reference.shiftedBy(dt);
1492 FieldAbsoluteDate<T> after = shifted.shiftedBy(Precision.EPSILON);
1493 Assertions.assertEquals(624110398L, shifted.toAbsoluteDate().getSeconds());
1494 Assertions.assertEquals((1.0 - 1.6922e-13) * 1.0e18, shifted.toAbsoluteDate().getAttoSeconds(), 1.0e-15);
1495 Assertions.assertEquals(Precision.EPSILON, after.durationFrom(shifted).getReal(), 1.0e-18);
1496 }
1497
1498 private <T extends CalculusFieldElement<T>> void doTestDurationFromWithTimeUnit(final Field<T> field) {
1499 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, 2023, 1, 1, 12, 13, 59.12334567, utc);
1500 for (TimeUnit timeUnit : TimeUnit.values()) {
1501 Assertions.assertEquals(field.getZero(), reference.durationFrom(reference, timeUnit));
1502
1503 long dayInTimeUnit = timeUnit.convert((long) Constants.JULIAN_DAY, TimeUnit.SECONDS);
1504 for (int i = 1; i <= 365; i++) {
1505 FieldAbsoluteDate<T> minusDays = reference.shiftedBy(-i * Constants.JULIAN_DAY);
1506 FieldAbsoluteDate<T> plusDays = reference.shiftedBy(i* Constants.JULIAN_DAY);
1507
1508
1509 Assertions.assertEquals(field.getZero().add(i * dayInTimeUnit), reference.durationFrom(minusDays, timeUnit));
1510
1511 Assertions.assertEquals(field.getZero().add(-i * dayInTimeUnit), reference.durationFrom(plusDays, timeUnit));
1512
1513 AbsoluteDate minusDaysA = minusDays.toAbsoluteDate();
1514 AbsoluteDate plusDaysA = plusDays.toAbsoluteDate();
1515
1516 Assertions.assertEquals(field.getZero().add(i * dayInTimeUnit), reference.durationFrom(minusDaysA, timeUnit));
1517
1518 Assertions.assertEquals(field.getZero().add(-i * dayInTimeUnit), reference.durationFrom(plusDaysA, timeUnit));
1519 }
1520
1521 for (long ns = 1; ns <= 1_000_000_000; ns += 1_000_000) {
1522 FieldAbsoluteDate<T> minus = reference.shiftedBy(-1e-9 * ns);
1523 FieldAbsoluteDate<T> plus = reference.shiftedBy(1e-9 * ns);
1524
1525 double deltaInTimeUnit = ns / (double) timeUnit.toNanos(1);
1526 Assertions.assertEquals(field.getZero().add(FastMath.round(deltaInTimeUnit)), reference.durationFrom(minus, timeUnit),
1527 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1528
1529 Assertions.assertEquals(field.getZero().add(FastMath.round(-deltaInTimeUnit)), reference.durationFrom(plus, timeUnit),
1530 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1531
1532 AbsoluteDate minusA = minus.toAbsoluteDate();
1533 AbsoluteDate plusA = plus.toAbsoluteDate();
1534
1535 Assertions.assertEquals(field.getZero().add(FastMath.round(deltaInTimeUnit)), reference.durationFrom(minusA, timeUnit),
1536 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1537
1538 Assertions.assertEquals(field.getZero().add(FastMath.round(-deltaInTimeUnit)), reference.durationFrom(plusA, timeUnit),
1539 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1540 }
1541
1542
1543 }
1544 }
1545
1546 public <T extends CalculusFieldElement<T>> void doTestConstructWithTimeUnitOffset(final Field<T> field) {
1547 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, 2023, 1, 1, 12, 13, 59.12334567, utc);
1548
1549 for (TimeUnit timeUnit : TimeUnit.values()) {
1550 Assertions.assertEquals(0,
1551 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(reference, 0, timeUnit)).getReal()), 1e-10);
1552
1553 long dayInTimeUnit = timeUnit.convert((long) Constants.JULIAN_DAY, TimeUnit.SECONDS);
1554 for (int i = 1; i <= 365; i++) {
1555 FieldAbsoluteDate<T> minusDays = reference.shiftedBy(-i * Constants.JULIAN_DAY);
1556 FieldAbsoluteDate<T> plusDays = reference.shiftedBy(i* Constants.JULIAN_DAY);
1557
1558 Assertions.assertEquals(0,
1559 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(minusDays, i * dayInTimeUnit, timeUnit)).getReal()),
1560 1e-10,
1561 String.format("TimeUnit: %s", timeUnit));
1562 Assertions.assertEquals(0,
1563 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(plusDays, -i * dayInTimeUnit, timeUnit)).getReal()),
1564 1e-10,
1565 String.format("TimeUnit: %s", timeUnit));
1566
1567 Assertions.assertEquals(0,
1568 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(minusDays.toAbsoluteDate(), i * dayInTimeUnit, timeUnit, field)).getReal()),
1569 1e-10,
1570 String.format("TimeUnit: %s", timeUnit));
1571 Assertions.assertEquals(0,
1572 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(plusDays.toAbsoluteDate(), -i * dayInTimeUnit, timeUnit, field)).getReal()),
1573 1e-10,
1574 String.format("TimeUnit: %s", timeUnit));
1575 }
1576
1577 for (long ns = 1; ns <= 1_000_000_000; ns += 1_000_000) {
1578 if (timeUnit.convert(1, TimeUnit.SECONDS) < 1) {
1579
1580 continue;
1581 }
1582 FieldAbsoluteDate<T> minus = reference.shiftedBy(-1e-9 * ns);
1583 FieldAbsoluteDate<T> plus = reference.shiftedBy(1e-9 * ns);
1584
1585 double deltaInTimeUnit = ns / (double) timeUnit.toNanos(1);
1586 Assertions.assertEquals(0,
1587 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(minus, FastMath.round(deltaInTimeUnit), timeUnit)).getReal()),
1588 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1589 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1590 Assertions.assertEquals(0,
1591 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(plus, FastMath.round(-deltaInTimeUnit), timeUnit)).getReal()),
1592 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1593 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1594
1595 Assertions.assertEquals(0,
1596 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(minus.toAbsoluteDate(), FastMath.round(deltaInTimeUnit), timeUnit, field)).getReal()),
1597 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1598 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1599 Assertions.assertEquals(0,
1600 FastMath.abs(reference.durationFrom(new FieldAbsoluteDate<>(plus.toAbsoluteDate(), FastMath.round(-deltaInTimeUnit), timeUnit, field)).getReal()),
1601 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1602 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1603 }
1604 }
1605 }
1606
1607 public <T extends CalculusFieldElement<T>> void doTestShiftedByWithTimeUnit(final Field<T> field) {
1608 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, 2023, 1, 1, 12, 13, 59.12334567, utc);
1609
1610 for (TimeUnit timeUnit : TimeUnit.values()) {
1611 Assertions.assertEquals(0,
1612 FastMath.abs(reference.durationFrom(reference.shiftedBy(0, timeUnit)).getReal()), 1e-10);
1613
1614 long dayInTimeUnit = timeUnit.convert((long) Constants.JULIAN_DAY, TimeUnit.SECONDS);
1615 for (int i = 1; i <= 365; i++) {
1616 FieldAbsoluteDate<T> minusDays = reference.shiftedBy(-i * Constants.JULIAN_DAY);
1617 FieldAbsoluteDate<T> plusDays = reference.shiftedBy(i* Constants.JULIAN_DAY);
1618
1619 Assertions.assertEquals(0,
1620 FastMath.abs(reference.durationFrom(minusDays.shiftedBy( i * dayInTimeUnit, timeUnit)).getReal()),
1621 1e-10,
1622 String.format("TimeUnit: %s", timeUnit));
1623 Assertions.assertEquals(0,
1624 FastMath.abs(reference.durationFrom(plusDays.shiftedBy( -i * dayInTimeUnit, timeUnit)).getReal()),
1625 1e-10,
1626 String.format("TimeUnit: %s", timeUnit));
1627
1628 }
1629
1630 for (long ns = 1; ns <= 1_000_000_000; ns += 1_000_000) {
1631 if (timeUnit.convert(1, TimeUnit.SECONDS) < 1) {
1632
1633 continue;
1634 }
1635 FieldAbsoluteDate<T> minus = reference.shiftedBy(-1e-9 * ns);
1636 FieldAbsoluteDate<T> plus = reference.shiftedBy(1e-9 * ns);
1637
1638 double deltaInTimeUnit = ns / (double) timeUnit.toNanos(1);
1639 Assertions.assertEquals(0,
1640 FastMath.abs(reference.durationFrom(minus.shiftedBy(FastMath.round(deltaInTimeUnit), timeUnit)).getReal()),
1641 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1642 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1643 Assertions.assertEquals(0,
1644 FastMath.abs(reference.durationFrom(plus.shiftedBy(FastMath.round(-deltaInTimeUnit), timeUnit)).getReal()),
1645 1.0 / timeUnit.convert(1, TimeUnit.SECONDS),
1646 String.format("TimeUnit: %s, ns: %d", timeUnit, ns));
1647 }
1648 }
1649 }
1650
1651 public <T extends CalculusFieldElement<T>> void doTestToStringWithoutUtcOffset(final Field<T> field) {
1652
1653 FieldAbsoluteDate<T> date = new FieldAbsoluteDate<>(field,2009, 1, 1, utc);
1654 double one = FastMath.nextDown(1.0);
1655 double zeroUlp = FastMath.nextUp(0.0);
1656 double oneUlp = FastMath.ulp(1.0);
1657
1658 double sixtyUlp = FastMath.ulp(60.0);
1659
1660
1661
1662 checkToStringNoOffset(date, "2009-01-01T00:00:00.000");
1663 checkToStringNoOffset(date.shiftedBy(1), "2009-01-01T00:00:01.000");
1664
1665 checkToStringNoOffset(date.shiftedBy(12.3456789123456789), "2009-01-01T00:00:12.346");
1666 checkToStringNoOffset(date.shiftedBy(0.0123456789123456789), "2009-01-01T00:00:00.012");
1667
1668 checkToStringNoOffset(date.shiftedBy(zeroUlp), "2009-01-01T00:00:00.000");
1669
1670 checkToStringNoOffset(date.shiftedBy(59.0).shiftedBy(one), "2009-01-01T00:01:00.000");
1671
1672 checkToStringNoOffset(date.shiftedBy(86399).shiftedBy(one), "2009-01-02T00:00:00.000");
1673 checkToStringNoOffset(date.shiftedBy(oneUlp), "2009-01-01T00:00:00.000");
1674 checkToStringNoOffset(date.shiftedBy(one), "2009-01-01T00:00:01.000");
1675 checkToStringNoOffset(date.shiftedBy(-zeroUlp), "2009-01-01T00:00:00.000");
1676
1677
1678 checkToStringNoOffset(date.shiftedBy(-oneUlp), "2009-01-01T00:00:00.000");
1679
1680 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(one), "2009-01-01T00:00:00.000");
1681 checkToStringNoOffset(date.shiftedBy(-0.5), "2008-12-31T23:59:60.500");
1682 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(zeroUlp), "2008-12-31T23:59:60.000");
1683 checkToStringNoOffset(date.shiftedBy(-1), "2008-12-31T23:59:60.000");
1684 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(-zeroUlp), "2008-12-31T23:59:60.000");
1685 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(-oneUlp), "2008-12-31T23:59:60.000");
1686 checkToStringNoOffset(date.shiftedBy(-2), "2008-12-31T23:59:59.000");
1687
1688 checkToStringNoOffset(date.shiftedBy(-1).shiftedBy(-sixtyUlp), "2008-12-31T23:59:60.000");
1689 checkToStringNoOffset(date.shiftedBy(-61).shiftedBy(zeroUlp), "2008-12-31T23:59:00.000");
1690 checkToStringNoOffset(date.shiftedBy(-61).shiftedBy(oneUlp), "2008-12-31T23:59:00.000");
1691 }
1692
1693
1694 private <T extends CalculusFieldElement<T>> void checkToStringNoOffset(final FieldAbsoluteDate<T> d, final String s) {
1695 MatcherAssert.assertThat(d.toStringWithoutUtcOffset(utc, 3), CoreMatchers.is(s));
1696 MatcherAssert.assertThat(
1697 d.getComponents(utc).toStringWithoutUtcOffset(utc.minuteDuration(d), 3),
1698 CoreMatchers.is(s));
1699 }
1700
1701 private <T extends CalculusFieldElement<T>> void check(FieldAbsoluteDate<T> date,
1702 int year, int month, int day, int hour, int minute, double second,
1703 double roundTripUlps, final int secondUlps, final double absTol) {
1704 DateTimeComponents actual = date.getComponents(utc);
1705 DateComponents d = actual.getDate();
1706 TimeComponents t = actual.getTime();
1707 MatcherAssert.assertThat(d.getYear(), CoreMatchers.is(year));
1708 MatcherAssert.assertThat(d.getMonth(), CoreMatchers.is(month));
1709 MatcherAssert.assertThat(d.getDay(), CoreMatchers.is(day));
1710 MatcherAssert.assertThat(t.getHour(), CoreMatchers.is(hour));
1711 MatcherAssert.assertThat(t.getMinute(), CoreMatchers.is(minute));
1712 MatcherAssert.assertThat("second", t.getSecond(),
1713 OrekitMatchers.numberCloseTo(second, absTol, secondUlps));
1714 MatcherAssert.assertThat(t.getMinutesFromUTC(), CoreMatchers.is(0));
1715 final double tol = FastMath.ulp(second) * roundTripUlps;
1716 final double difference = new FieldAbsoluteDate<>(date.getField(), actual, utc)
1717 .durationFrom(date).getReal();
1718 MatcherAssert.assertThat(difference,
1719 OrekitMatchers.closeTo(0, FastMath.max(absTol, tol)));
1720 }
1721
1722 static class AnyFieldTimeStamped<T extends CalculusFieldElement<T>> implements FieldTimeStamped<T> {
1723 AbsoluteDate date;
1724 Field<T> field;
1725
1726 public AnyFieldTimeStamped(Field<T> field, AbsoluteDate date) {
1727 this.date = date;
1728 this.field = field;
1729 }
1730
1731 @Override
1732 public FieldAbsoluteDate<T> getDate() {
1733 return new FieldAbsoluteDate<>(field, date);
1734 }
1735 }
1736
1737 static class TestDates<T extends CalculusFieldElement<T>> {
1738 private final AbsoluteDate presentDate;
1739 private final AnyFieldTimeStamped<T> present;
1740 private final AnyFieldTimeStamped<T> past;
1741 private final AnyFieldTimeStamped<T> presentToo;
1742 private final AnyFieldTimeStamped<T> future;
1743
1744 public TestDates(Field<T> field) {
1745 presentDate = new AbsoluteDate(new DateComponents(2000, 1, 1),
1746 new TimeComponents(12, 0, 0),
1747 TimeScalesFactory.getUTC());
1748 present = new AnyFieldTimeStamped<>(field, presentDate);
1749 presentToo = new AnyFieldTimeStamped<>(field, presentDate.shiftedBy(0));
1750 past = new AnyFieldTimeStamped<>(field, presentDate.shiftedBy(-1000));
1751 future = new AnyFieldTimeStamped<>(field, presentDate.shiftedBy(1000));
1752 }
1753
1754 public FieldAbsoluteDate<T> getPresentFieldAbsoluteDate() {
1755 return present.getDate();
1756 }
1757 }
1758
1759 @Test
1760 public void doTestGetJulianDatesWithBinar64() {
1761
1762 final Field<Binary64> field = Binary64Field.getInstance();
1763
1764
1765 doTestGetJulianDates(field);
1766 }
1767
1768 public <T extends CalculusFieldElement<T>> void doTestGetJulianDates(Field<T> field) {
1769
1770 final T one = field.getOne();
1771 final TimeScale utc = TimeScalesFactory.getUTC();
1772
1773 FieldAbsoluteDate<T> reference = new FieldAbsoluteDate<>(field, 2024, 7, 4, 13, 0, 0, utc);
1774 FieldAbsoluteDate<T> referenceFromJDMethod =
1775 FieldAbsoluteDate.createJDDate(2460496, one.multiply(0.0416667 * Constants.JULIAN_DAY), utc);
1776 FieldAbsoluteDate<T> referenceFromMJDMethod =
1777 FieldAbsoluteDate.createMJDDate(60495, one.multiply(0.54166670 * Constants.JULIAN_DAY), utc);
1778
1779
1780 T mjdDateDefaultData = reference.getMJD();
1781 T jdDateDefaultData = reference.getJD();
1782 T mjdDate = reference.getMJD(utc);
1783 T jdDate = reference.getJD(utc);
1784
1785
1786
1787 Assertions.assertEquals(2460496.0416667, jdDateDefaultData.getReal(), 1.0e-6);
1788 Assertions.assertEquals(60495.54166670, mjdDateDefaultData.getReal(), 1.0e-6);
1789 Assertions.assertEquals(jdDate, jdDateDefaultData);
1790 Assertions.assertEquals(mjdDate, mjdDateDefaultData);
1791
1792
1793 Assertions.assertTrue(reference.isCloseTo(referenceFromJDMethod, 1e-2));
1794 Assertions.assertTrue(reference.isCloseTo(referenceFromMJDMethod, 1e-2));
1795 }
1796
1797 @Test
1798 void testGetJD() {
1799
1800 final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
1801 final FieldAbsoluteDate<UnivariateDerivative1> fieldDate = new FieldAbsoluteDate<>(UnivariateDerivative1Field.getInstance(),
1802 date).shiftedBy(new UnivariateDerivative1(0., 1));
1803
1804 final UnivariateDerivative1 jdField = fieldDate.getJD();
1805
1806 final double shift = 10.;
1807 final FieldAbsoluteDate<UnivariateDerivative1> shiftedDate = fieldDate.shiftedBy(shift);
1808 final double expectedJdDerivative = (shiftedDate.getJD().getReal() - jdField.getReal()) / shift;
1809 Assertions.assertEquals(expectedJdDerivative, jdField.getFirstDerivative(), 1e-10);
1810 }
1811
1812 @Test
1813 void testGetMJD() {
1814
1815 final AbsoluteDate date = AbsoluteDate.ARBITRARY_EPOCH;
1816 final FieldAbsoluteDate<UnivariateDerivative1> fieldDate = new FieldAbsoluteDate<>(UnivariateDerivative1Field.getInstance(),
1817 date).shiftedBy(new UnivariateDerivative1(0., 1));
1818
1819 final UnivariateDerivative1 mjdField = fieldDate.getMJD();
1820
1821 final double shift = 10.;
1822 final FieldAbsoluteDate<UnivariateDerivative1> shiftedDate = fieldDate.shiftedBy(shift);
1823 final double expectedMjdDerivative = (shiftedDate.getMJD().getReal() - mjdField.getReal()) / shift;
1824 Assertions.assertEquals(expectedMjdDerivative, mjdField.getFirstDerivative(), 1e-10);
1825 }
1826
1827 @Test
1828 void testMedian() {
1829 final AbsoluteDate date1 = new AbsoluteDate(2003, 6, 13, 14, 15,
1830 new TimeOffset(53, TimeOffset.SECOND, 12, TimeOffset.ATTOSECOND),
1831 TimeScalesFactory.getTT());
1832 final FieldAbsoluteDate<UnivariateDerivative1> fieldDate1 =
1833 new FieldAbsoluteDate<>(UnivariateDerivative1Field.getInstance(), date1).
1834 shiftedBy(new UnivariateDerivative1(0.0, 1.0));
1835 final AbsoluteDate date2 = new AbsoluteDate(2003, 6, 13, 14, 17,
1836 new TimeOffset(25, TimeOffset.SECOND, 120, TimeOffset.ATTOSECOND),
1837 TimeScalesFactory.getTT());
1838 final FieldAbsoluteDate<UnivariateDerivative1> fieldDate2 =
1839 new FieldAbsoluteDate<>(UnivariateDerivative1Field.getInstance(), date2).
1840 shiftedBy(new UnivariateDerivative1(0.0, 2.0));
1841 final AbsoluteDate dateM = new AbsoluteDate(2003, 6, 13, 14, 16,
1842 new TimeOffset(39, TimeOffset.SECOND, 66, TimeOffset.ATTOSECOND),
1843 TimeScalesFactory.getTT());
1844 final FieldAbsoluteDate<UnivariateDerivative1> fieldDateM =
1845 new FieldAbsoluteDate<>(UnivariateDerivative1Field.getInstance(), dateM).
1846 shiftedBy(new UnivariateDerivative1(0.0, 1.5));
1847 Assertions.assertEquals(fieldDateM, FieldAbsoluteDate.createMedian(fieldDate1, fieldDate2));
1848 Assertions.assertEquals(fieldDateM, FieldAbsoluteDate.createMedian(fieldDate2, fieldDate1));
1849 }
1850
1851 @Test
1852 void testMedianInfinite() {
1853 final FieldAbsoluteDate<Binary64> future = FieldAbsoluteDate.getFutureInfinity(Binary64Field.getInstance());
1854 final FieldAbsoluteDate<Binary64> past = FieldAbsoluteDate.getPastInfinity(Binary64Field.getInstance());
1855 final FieldAbsoluteDate<Binary64> arbitrary = FieldAbsoluteDate.getArbitraryEpoch(Binary64Field.getInstance());
1856 Assertions.assertEquals(future, FieldAbsoluteDate.createMedian(future, arbitrary));
1857 Assertions.assertEquals(past, FieldAbsoluteDate.createMedian(past, arbitrary));
1858 }
1859
1860 @Test
1861 void testToFUD1Field() {
1862
1863 final Field<Binary64> field = Binary64Field.getInstance();
1864 final FieldAbsoluteDate<Binary64> date = FieldAbsoluteDate.getArbitraryEpoch(field);
1865
1866 final FieldAbsoluteDate<FieldUnivariateDerivative1<Binary64>> ud1Date = date.toFUD1Field();
1867
1868 Assertions.assertEquals(date.toAbsoluteDate(), ud1Date.toAbsoluteDate());
1869 final FieldUnivariateDerivative1<Binary64> shift = ud1Date.durationFrom(date.toAbsoluteDate());
1870 Assertions.assertEquals(field.getOne(), shift.getFirstDerivative());
1871 }
1872
1873 @Test
1874 void testToFUD2Field() {
1875
1876 final Field<Binary64> field = Binary64Field.getInstance();
1877 final FieldAbsoluteDate<Binary64> date = FieldAbsoluteDate.getArbitraryEpoch(field);
1878
1879 final FieldAbsoluteDate<FieldUnivariateDerivative2<Binary64>> ud2Date = date.toFUD2Field();
1880
1881 Assertions.assertEquals(date.toAbsoluteDate(), ud2Date.toAbsoluteDate());
1882 final FieldUnivariateDerivative2<Binary64> shift = ud2Date.durationFrom(date.toAbsoluteDate());
1883 Assertions.assertEquals(field.getOne(), shift.getFirstDerivative());
1884 Assertions.assertEquals(field.getZero(), shift.getSecondDerivative());
1885 }
1886
1887 private <T extends CalculusFieldElement<T>> void doTestGetDayOfYear(final Field<T> field) {
1888 Assertions.assertEquals(0.501,
1889 new FieldAbsoluteDate<>(field,
1890 new AbsoluteDate(2004, 1, 1, 0, 0, 0.001, utc)).
1891 getDayOfYear(utc).getReal(),
1892 1.0e-3);
1893 Assertions.assertEquals(1.000,
1894 new FieldAbsoluteDate<>(field,
1895 new AbsoluteDate(2004, 1, 1, 12, 0, 0.000, utc)).
1896 getDayOfYear(utc).getReal(),
1897 1.0e-3);
1898 Assertions.assertEquals(366.0,
1899 new FieldAbsoluteDate<>(field,
1900 new AbsoluteDate(2004, 12, 31, 12, 0, 0.000, utc)).
1901 getDayOfYear(utc).getReal(),
1902 1.0e-3);
1903 Assertions.assertEquals(366.499999988426,
1904 new FieldAbsoluteDate<>(field,
1905 new AbsoluteDate(2004, 12, 31, 23, 59, 59.999, utc)).
1906 getDayOfYear(utc).getReal(),
1907 1.0e-12);
1908 Assertions.assertEquals(0.500000011574,
1909 new FieldAbsoluteDate<>(field,
1910 new AbsoluteDate(2004, 12, 31, 23, 59, 59.999, utc).shiftedBy(0.002)).
1911 getDayOfYear(utc).getReal(),
1912 1.0e-12);
1913 }
1914
1915 }