001/*
002 * Shredzone Commons - suncalc
003 *
004 * Copyright (C) 2017 Richard "Shred" Körber
005 *   http://commons.shredzone.org
006 *
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
013 */
014package org.shredzone.commons.suncalc.util;
015
016import static java.lang.Math.PI;
017import static org.assertj.core.api.Assertions.assertThat;
018import static org.assertj.core.data.Offset.offset;
019
020import java.time.ZoneId;
021import java.time.ZonedDateTime;
022
023import org.assertj.core.api.AbstractDateAssert;
024import org.assertj.core.data.Offset;
025import org.junit.BeforeClass;
026import org.junit.Test;
027
028/**
029 * Unit tests for {@link JulianDate}.
030 */
031public class JulianDateTest {
032
033    private static final Offset<Double> ERROR = Offset.offset(0.001);
034
035    @BeforeClass
036    public static void init() {
037        AbstractDateAssert.registerCustomDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
038    }
039
040    @Test
041    public void testAtHour() {
042        JulianDate jd = new JulianDate(of(2017, 8, 19, 0, 0, 0, "UTC"));
043        assertDate(jd, "2017-08-19T00:00:00Z");
044
045        JulianDate jd2 = jd.atHour(8.5);
046        assertDate(jd2, "2017-08-19T08:30:00Z");
047
048        JulianDate jd3 = new JulianDate(of(2017, 8, 19, 0, 0, 0, "Europe/Berlin"));
049        assertDate(jd3, "2017-08-19T00:00:00+02:00");
050
051        JulianDate jd4 = jd3.atHour(8.5);
052        assertDate(jd4, "2017-08-19T08:30:00+02:00");
053    }
054
055    @Test
056    public void testModifiedJulianDate() {
057        // MJD epoch is midnight of November 17th, 1858.
058        JulianDate jd1 = new JulianDate(of(1858, 11, 17, 0, 0, 0, "UTC"));
059        assertThat(jd1.getModifiedJulianDate()).isZero();
060        assertThat(jd1.toString()).isEqualTo("0d 00h 00m 00s");
061
062        JulianDate jd2 = new JulianDate(of(2017, 8, 19, 15, 6, 16, "UTC"));
063        assertThat(jd2.getModifiedJulianDate()).isCloseTo(57984.629, ERROR);
064        assertThat(jd2.toString()).isEqualTo("57984d 15h 06m 16s");
065
066        JulianDate jd3 = new JulianDate(of(2017, 8, 19, 15, 6, 16, "GMT+2"));
067        assertThat(jd3.getModifiedJulianDate()).isCloseTo(57984.546, ERROR);
068        assertThat(jd3.toString()).isEqualTo("57984d 13h 06m 16s");
069    }
070
071    @Test
072    public void testJulianCentury() {
073        JulianDate jd1 = new JulianDate(of(2000, 1, 1, 0, 0, 0, "UTC"));
074        assertThat(jd1.getJulianCentury()).isCloseTo(0.0, ERROR);
075
076        JulianDate jd2 = new JulianDate(of(2017, 1, 1, 0, 0, 0, "UTC"));
077        assertThat(jd2.getJulianCentury()).isCloseTo(0.17, ERROR);
078
079        JulianDate jd3 = new JulianDate(of(2050, 7, 1, 0, 0, 0, "UTC"));
080        assertThat(jd3.getJulianCentury()).isCloseTo(0.505, ERROR);
081    }
082
083    @Test
084    public void testGreenwichMeanSiderealTime() {
085        JulianDate jd1 = new JulianDate(of(2017, 9, 3, 19, 5, 15, "UTC"));
086        assertThat(jd1.getGreenwichMeanSiderealTime()).isCloseTo(4.702, ERROR);
087
088    }
089
090    @Test
091    public void testTrueAnomaly() {
092        JulianDate jd1 = new JulianDate(of(2017, 1, 4, 0, 0, 0, "UTC"));
093        assertThat(jd1.getTrueAnomaly()).isCloseTo(0.0, offset(0.1));
094
095        JulianDate jd2 = new JulianDate(of(2017, 7, 4, 0, 0, 0, "UTC"));
096        assertThat(jd2.getTrueAnomaly()).isCloseTo(PI, offset(0.1));
097    }
098
099    @Test
100    public void testAtModifiedJulianDate() {
101        JulianDate jd1 = new JulianDate(of(2017, 8, 19, 15, 6, 16, "UTC"));
102
103        JulianDate jd2 = new JulianDate(ZonedDateTime.now(ZoneId.of("UTC")))
104                        .atModifiedJulianDate(jd1.getModifiedJulianDate());
105
106        assertThat(jd2.getDateTime()).isEqualTo(jd1.getDateTime());
107    }
108
109    @Test
110    public void testAtJulianCentury() {
111        JulianDate jd1 = new JulianDate(of(2017, 1, 1, 0, 0, 0, "UTC"));
112
113        JulianDate jd2 = new JulianDate(ZonedDateTime.now(ZoneId.of("UTC")))
114                        .atJulianCentury(jd1.getJulianCentury());
115
116        assertThat(jd2.getDateTime()).isEqualTo(jd1.getDateTime());
117    }
118
119    private ZonedDateTime of(int year, int month, int day, int hour, int minute, int second, String zone) {
120        return ZonedDateTime.of(year, month, day, hour, minute, second, 0, ZoneId.of(zone));
121    }
122
123    private void assertDate(JulianDate jd, String date) {
124        assertThat(jd.getDateTime()).isEqualTo(date);
125    }
126
127}