/* Copyright 2002-2017 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.time;
import org.junit.Assert;
import org.junit.Test;
public class DateComponentsTest {
@Test
public void testReferenceDates() {
int[][] reference = {
{ -4713, 12, 31, -2451546 }, { -4712, 01, 01, -2451545 },
{ 0000, 12, 31, -730122 }, { 0001, 01, 01, -730121 },
{ 1500, 02, 28, -182554 }, { 1500, 02, 29, -182553 },
{ 1500, 03, 01, -182552 }, { 1582, 10, 04, -152385 },
{ 1582, 10, 15, -152384 }, { 1600, 02, 28, -146039 },
{ 1600, 02, 29, -146038 }, { 1600, 03, 01, -146037 },
{ 1700, 02, 28, -109514 }, { 1700, 03, 01, -109513 },
{ 1800, 02, 28, -72990 }, { 1800, 03, 01, -72989 },
{ 1858, 11, 15, -51546 }, { 1858, 11, 16, -51545 },
{ 1999, 12, 31, -1 }, { 2000, 01, 01, 0 },
{ 2000, 02, 28, 58 }, { 2000, 02, 29, 59 },
{ 2000, 03, 01, 60 }
};
for (int i = 0; i < reference.length; ++i) {
int day = reference[i][3];
DateComponents date = new DateComponents(DateComponents.J2000_EPOCH, day);
Assert.assertEquals(reference[i][0], date.getYear());
Assert.assertEquals(reference[i][1], date.getMonth());
Assert.assertEquals(reference[i][2], date.getDay());
}
}
@Test
public void testCalendarWeek() {
Assert.assertEquals(52, new DateComponents(1995, 1, 1).getCalendarWeek());
Assert.assertEquals(52, new DateComponents(1996, 12, 29).getCalendarWeek());
Assert.assertEquals( 1, new DateComponents(1996, 12, 30).getCalendarWeek());
Assert.assertEquals( 1, new DateComponents(1997, 1, 5).getCalendarWeek());
Assert.assertEquals(52, new DateComponents(1997, 12, 28).getCalendarWeek());
Assert.assertEquals( 1, new DateComponents(1997, 12, 29).getCalendarWeek());
Assert.assertEquals( 1, new DateComponents(1998, 1, 4).getCalendarWeek());
Assert.assertEquals( 2, new DateComponents(1998, 1, 5).getCalendarWeek());
Assert.assertEquals(52, new DateComponents(1998, 12, 27).getCalendarWeek());
Assert.assertEquals(53, new DateComponents(1998, 12, 28).getCalendarWeek());
Assert.assertEquals(53, new DateComponents(1999, 1, 3).getCalendarWeek());
Assert.assertEquals( 1, new DateComponents(1999, 1, 4).getCalendarWeek());
DateComponents[] firstWeekMonday = new DateComponents[502];
for (int i = 0; i < firstWeekMonday.length; ++i) {
firstWeekMonday[i] = firstWeekMonday(1599 + i);
}
int startDay = firstWeekMonday[0].getJ2000Day();
int endDay = firstWeekMonday[firstWeekMonday.length - 1].getJ2000Day();
int index = 0;
for (int day = startDay; day < endDay; ++day) {
DateComponents d = new DateComponents(day);
if (firstWeekMonday[index + 1].compareTo(d) <= 0) {
++index;
}
int delta = d.getJ2000Day() - firstWeekMonday[index].getJ2000Day();
Assert.assertEquals(1 + delta / 7, d.getCalendarWeek());
}
}
@Test
public void testWeekComponents() {
int[][] reference = {
{ 1994, 52, 7, 1995, 1, 1 },
{ 1996, 52, 7, 1996, 12, 29 },
{ 1997, 1, 1, 1996, 12, 30 },
{ 1997, 1, 7, 1997, 1, 5 },
{ 1997, 52, 7, 1997, 12, 28 },
{ 1998, 1, 1, 1997, 12, 29 },
{ 1998, 1, 7, 1998, 1, 4 },
{ 1998, 2, 1, 1998, 1, 5 },
{ 1998, 52, 7, 1998, 12, 27 },
{ 1998, 53, 1, 1998, 12, 28 },
{ 1998, 53, 7, 1999, 1, 3 },
{ 1999, 1, 1, 1999, 1, 4 },
{ 1582, 40, 4, 1582, 10, 4 },
{ 1582, 40, 5, 1582, 10, 15 },
{ 1582, 51, 5, 1582, 12, 31 },
{ 1582, 51, 6, 1583, 1, 1 },
{ 1582, 51, 7, 1583, 1, 2 },
{ 1583, 1, 1, 1583, 1, 3 }
};
for (int i = 0; i < reference.length; ++i) {
int[] refI = reference[i];
DateComponents date = DateComponents.createFromWeekComponents(refI[0], refI[1], refI[2]);
Assert.assertEquals(refI[3], date.getYear());
Assert.assertEquals(refI[4], date.getMonth());
Assert.assertEquals(refI[5], date.getDay());
}
}
// poor man's (slow) implementation of first calendar week computation, using ISO rules
private DateComponents firstWeekMonday(final int year) {
int i = 0;
while (true) {
DateComponents d = new DateComponents(year, 1, ++i);
if (d.getDayOfWeek() == 4) {
// this is the first Thursday of the year, Monday is 3 days before
return new DateComponents(d, -3);
}
}
}
@Test
public void testDayOfWeek() {
Assert.assertEquals(7, new DateComponents(-4713, 12, 31).getDayOfWeek());
Assert.assertEquals(1, new DateComponents(-4712, 01, 01).getDayOfWeek());
Assert.assertEquals(4, new DateComponents( 1582, 10, 04).getDayOfWeek());
Assert.assertEquals(5, new DateComponents( 1582, 10, 15).getDayOfWeek());
Assert.assertEquals(5, new DateComponents( 1999, 12, 31).getDayOfWeek());
Assert.assertEquals(6, new DateComponents( 2000, 01, 01).getDayOfWeek());
}
@Test
public void testDayOfYear() {
Assert.assertEquals( 1, new DateComponents(2003, 1, 1).getDayOfYear());
Assert.assertEquals(365, new DateComponents(2003, 12, 31).getDayOfYear());
Assert.assertEquals(366, new DateComponents(2004, 12, 31).getDayOfYear());
Assert.assertEquals( 59, new DateComponents(2003, 2, 28).getDayOfYear());
Assert.assertEquals( 60, new DateComponents(2003, 3, 1).getDayOfYear());
Assert.assertEquals( 59, new DateComponents(2004, 2, 28).getDayOfYear());
Assert.assertEquals( 60, new DateComponents(2004, 2, 29).getDayOfYear());
Assert.assertEquals( 61, new DateComponents(2004, 3, 1).getDayOfYear());
Assert.assertEquals(269, new DateComponents(2003, 9, 26).getDayOfYear());
}
@Test
public void testParse() {
Assert.assertEquals(-2451546, DateComponents.parseDate("-47131231").getJ2000Day());
Assert.assertEquals(-2451546, DateComponents.parseDate("-4713-12-31").getJ2000Day());
Assert.assertEquals(-2451545, DateComponents.parseDate("-47120101").getJ2000Day());
Assert.assertEquals(-2451545, DateComponents.parseDate("-4712-01-01").getJ2000Day());
Assert.assertEquals( -730122, DateComponents.parseDate("00001231").getJ2000Day());
Assert.assertEquals( -730122, DateComponents.parseDate("0000-12-31").getJ2000Day());
Assert.assertEquals( -730121, DateComponents.parseDate("00010101").getJ2000Day());
Assert.assertEquals( -730121, DateComponents.parseDate("0001-01-01").getJ2000Day());
Assert.assertEquals( -182554, DateComponents.parseDate("15000228").getJ2000Day());
Assert.assertEquals( -182554, DateComponents.parseDate("1500-02-28").getJ2000Day());
Assert.assertEquals( -182553, DateComponents.parseDate("15000229").getJ2000Day());
Assert.assertEquals( -182553, DateComponents.parseDate("1500-02-29").getJ2000Day());
Assert.assertEquals( -182552, DateComponents.parseDate("15000301").getJ2000Day());
Assert.assertEquals( -182552, DateComponents.parseDate("1500-03-01").getJ2000Day());
Assert.assertEquals( -152385, DateComponents.parseDate("15821004").getJ2000Day());
Assert.assertEquals( -152385, DateComponents.parseDate("1582-10-04").getJ2000Day());
Assert.assertEquals( -152385, DateComponents.parseDate("1582W404").getJ2000Day());
Assert.assertEquals( -152385, DateComponents.parseDate("1582-W40-4").getJ2000Day());
Assert.assertEquals( -152384, DateComponents.parseDate("15821015").getJ2000Day());
Assert.assertEquals( -152384, DateComponents.parseDate("1582-10-15").getJ2000Day());
Assert.assertEquals( -152384, DateComponents.parseDate("1582W405").getJ2000Day());
Assert.assertEquals( -152384, DateComponents.parseDate("1582-W40-5").getJ2000Day());
Assert.assertEquals( -146039, DateComponents.parseDate("16000228").getJ2000Day());
Assert.assertEquals( -146039, DateComponents.parseDate("1600-02-28").getJ2000Day());
Assert.assertEquals( -146038, DateComponents.parseDate("16000229").getJ2000Day());
Assert.assertEquals( -146038, DateComponents.parseDate("1600-02-29").getJ2000Day());
Assert.assertEquals( -146037, DateComponents.parseDate("1600-03-01").getJ2000Day());
Assert.assertEquals( -109514, DateComponents.parseDate("17000228").getJ2000Day());
Assert.assertEquals( -109514, DateComponents.parseDate("1700-02-28").getJ2000Day());
Assert.assertEquals( -109513, DateComponents.parseDate("17000301").getJ2000Day());
Assert.assertEquals( -109513, DateComponents.parseDate("1700-03-01").getJ2000Day());
Assert.assertEquals( -72990, DateComponents.parseDate("18000228").getJ2000Day());
Assert.assertEquals( -72990, DateComponents.parseDate("1800-02-28").getJ2000Day());
Assert.assertEquals( -72989, DateComponents.parseDate("18000301").getJ2000Day());
Assert.assertEquals( -72989, DateComponents.parseDate("1800-03-01").getJ2000Day());
Assert.assertEquals( -51546, DateComponents.parseDate("18581115").getJ2000Day());
Assert.assertEquals( -51546, DateComponents.parseDate("1858-11-15").getJ2000Day());
Assert.assertEquals( -51545, DateComponents.parseDate("18581116").getJ2000Day());
Assert.assertEquals( -51545, DateComponents.parseDate("1858-11-16").getJ2000Day());
Assert.assertEquals( -1, DateComponents.parseDate("19991231").getJ2000Day());
Assert.assertEquals( -1, DateComponents.parseDate("1999-12-31").getJ2000Day());
Assert.assertEquals( 0, DateComponents.parseDate("20000101").getJ2000Day());
Assert.assertEquals( 0, DateComponents.parseDate("2000-01-01").getJ2000Day());
Assert.assertEquals( 0, DateComponents.parseDate("2000001").getJ2000Day());
Assert.assertEquals( 0, DateComponents.parseDate("2000-001").getJ2000Day());
Assert.assertEquals( 0, DateComponents.parseDate("1999-W52-6").getJ2000Day());
Assert.assertEquals( 0, DateComponents.parseDate("1999W526").getJ2000Day());
Assert.assertEquals( 58, DateComponents.parseDate("20000228").getJ2000Day());
Assert.assertEquals( 58, DateComponents.parseDate("2000-02-28").getJ2000Day());
Assert.assertEquals( 59, DateComponents.parseDate("20000229").getJ2000Day());
Assert.assertEquals( 59, DateComponents.parseDate("2000-02-29").getJ2000Day());
Assert.assertEquals( 60, DateComponents.parseDate("20000301").getJ2000Day());
Assert.assertEquals( 60, DateComponents.parseDate("2000-03-01").getJ2000Day());
}
@Test
public void testMonth() {
Assert.assertEquals(-51546, new DateComponents(1858, Month.NOVEMBER, 15).getJ2000Day());
Assert.assertEquals(-51546, new DateComponents(1858, Month.parseMonth("Nov"), 15).getJ2000Day());
Assert.assertEquals(Month.NOVEMBER, DateComponents.MODIFIED_JULIAN_EPOCH.getMonthEnum());
Assert.assertEquals(Month.JANUARY, DateComponents.J2000_EPOCH.getMonthEnum());
}
@Test
public void testISO8601Examples() {
Assert.assertEquals(-5377, DateComponents.parseDate("19850412").getJ2000Day());
Assert.assertEquals(-5377, DateComponents.parseDate("1985-04-12").getJ2000Day());
Assert.assertEquals(-5377, DateComponents.parseDate("1985102").getJ2000Day());
Assert.assertEquals(-5377, DateComponents.parseDate("1985-102").getJ2000Day());
Assert.assertEquals(-5377, DateComponents.parseDate("1985W155").getJ2000Day());
Assert.assertEquals(-5377, DateComponents.parseDate("1985-W15-5").getJ2000Day());
}
@Test
public void testComparisons() {
DateComponents[][] dates = {
{ new DateComponents(2003, 1, 1), new DateComponents(2003, 1) },
{ new DateComponents(2003, 2, 28), new DateComponents(2003, 59) },
{ new DateComponents(2003, 3, 1), new DateComponents(2003, 60) },
{ new DateComponents(2003, 9, 26), new DateComponents(2003, 269) },
{ new DateComponents(2003, 12, 31), new DateComponents(2003, 365) },
{ new DateComponents(2004, 2, 28), new DateComponents(2004, 59) },
{ new DateComponents(2004, 2, 29), new DateComponents(2004, 60) },
{ new DateComponents(2004, 3, 1), new DateComponents(2004, 61) },
{ new DateComponents(2004, 12, 31), new DateComponents(2004, 366) }
};
for (int i = 0; i < dates.length; ++i) {
for (int j = 0; j < dates.length; ++j) {
if (dates[i][0].compareTo(dates[j][1]) < 0) {
Assert.assertTrue(dates[j][1].compareTo(dates[i][0]) > 0);
Assert.assertFalse(dates[i][0].equals(dates[j][1]));
Assert.assertFalse(dates[j][1].equals(dates[i][0]));
Assert.assertTrue(dates[i][0].hashCode() != dates[j][1].hashCode());
Assert.assertTrue(i < j);
} else if (dates[i][0].compareTo(dates[j][1]) > 0) {
Assert.assertTrue(dates[j][1].compareTo(dates[i][0]) < 0);
Assert.assertFalse(dates[i][0].equals(dates[j][1]));
Assert.assertFalse(dates[j][1].equals(dates[i][0]));
Assert.assertTrue(dates[i][0].hashCode() != dates[j][1].hashCode());
Assert.assertTrue(i > j);
} else {
Assert.assertTrue(dates[j][1].compareTo(dates[i][0]) == 0);
Assert.assertTrue(dates[i][0].equals(dates[j][1]));
Assert.assertTrue(dates[j][1].equals(dates[i][0]));
Assert.assertTrue(dates[i][0].hashCode() == dates[j][1].hashCode());
Assert.assertTrue(i == j);
}
}
}
Assert.assertFalse(dates[0][0].equals(this));
}
@Test
public void testSymmetry() {
checkSymmetry(-2460000, 20000);
checkSymmetry( -740000, 20000);
checkSymmetry( -185000, 200000);
}
private void checkSymmetry(int start, int n) {
for (int i = start; i < start + n; ++i) {
DateComponents date1 = new DateComponents(DateComponents.J2000_EPOCH, i);
Assert.assertEquals(i, date1.getJ2000Day());
DateComponents date2 = new DateComponents(date1.getYear(), date1.getMonth(), date1.getDay());
Assert.assertEquals(i, date2.getJ2000Day());
}
}
@Test
public void testString() {
Assert.assertEquals("2000-01-01", new DateComponents(DateComponents.J2000_EPOCH, 0).toString());
Assert.assertEquals("-4713-12-31", new DateComponents(DateComponents.J2000_EPOCH, -2451546).toString());
}
@Test
public void testConstructorDoYYearBoundaries() {
Assert.assertNotNull(new DateComponents(2003, 1));
Assert.assertNotNull(new DateComponents(2003, 365));
Assert.assertNotNull(new DateComponents(2004, 1));
Assert.assertNotNull(new DateComponents(2004, 366));
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadDayA() {
new DateComponents(2003, 0);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadDayB() {
new DateComponents(2003, 366);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadDayC() {
new DateComponents(2004, 0);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadDayE() {
new DateComponents(2004, 367);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadWeek() {
DateComponents.createFromWeekComponents(2008, 53, 1);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadDayOfWeek1() {
DateComponents.createFromWeekComponents(2008, 43, 0);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadDayOfWeek2() {
DateComponents.createFromWeekComponents(2008, 43, 8);
}
@Test(expected=IllegalArgumentException.class)
public void testConstructorBadString() {
DateComponents.parseDate("197-05-01");
}
public void testWellFormed() {
checkWellFormed(-4800, -4700, -2483687, -2446797);
checkWellFormed( -5, 5, -732313, -728296);
checkWellFormed( 1580, 1605, -153392, -143906);
checkWellFormed( 1695, 1705, -111398, -107382);
checkWellFormed( 1795, 1805, -74874, -70858);
checkWellFormed( 1895, 1905, -38350, -34334);
checkWellFormed( 1995, 2005, -1826, 2191);
}
public void checkWellFormed(int startYear, int endYear, int startJ2000, int endJ2000) {
int[] commonLength = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int[] leapLength = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int k = startJ2000;
for (int year = startYear; year <= endYear; ++year) {
for (int month = 0; month < 14; ++month) {
for (int day = 0; day < 33; ++day) {
// ill-formed dates have predictable components
boolean expectedIllFormed = false;
if ((month < 1) || (month > 12)) {
expectedIllFormed = true;
} else if ((year == 1582) && (month == 10) && (day > 4) && (day < 15)) {
expectedIllFormed = true;
} else if ((year < 1582) && (year % 4 == 0)) {
if ((day < 1) || (day > leapLength[month])) {
expectedIllFormed = true;
}
} else if ((year >= 1582) && (year % 4 == 0) &&
((year % 100 != 0) || (year % 400 == 0))) {
if ((day < 1) || (day > leapLength[month])) {
expectedIllFormed = true;
}
} else {
if ((day < 1) || (day > commonLength[month])) {
expectedIllFormed = true;
}
}
try {
// well-formed dates should have sequential J2000 days
DateComponents date = new DateComponents(year, month, day);
Assert.assertEquals(k++, date.getJ2000Day());
Assert.assertTrue(!expectedIllFormed);
} catch (IllegalArgumentException iae) {
Assert.assertTrue(expectedIllFormed);
}
}
}
}
Assert.assertEquals(endJ2000, --k);
}
@Test
public void testMJD() {
Assert.assertEquals(0, DateComponents.MODIFIED_JULIAN_EPOCH.getMJD());
Assert.assertEquals(37665, new DateComponents(1962, 1, 1).getMJD());
Assert.assertEquals(54600, new DateComponents(2008, 5, 14).getMJD());
}
}