]> git.basschouten.com Git - openhab-addons.git/blob
56a3cce24e1ba171ef9e668c4a82affcae53f239
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.astro.internal.calc;
14
15 import static org.junit.jupiter.api.Assertions.*;
16
17 import java.util.Calendar;
18 import java.util.GregorianCalendar;
19 import java.util.TimeZone;
20
21 import org.junit.jupiter.api.BeforeEach;
22 import org.junit.jupiter.api.Test;
23 import org.openhab.binding.astro.internal.model.Moon;
24 import org.openhab.binding.astro.internal.model.ZodiacSign;
25
26 /***
27  * Specific unit tests to check if {@link MoonCalc} generates correct data for
28  * Amsterdam city on 27 February 2019. In particular the following cases are
29  * covered:
30  * <ul>
31  * <li>checks if generated data are the same (with some accuracy) as produced by
32  * haevens-above.com</li>
33  * </ul>
34  *
35  * @author Leo Siepel - Initial contribution
36  * @see <a href="https://www.heavens-above.com/Moon.aspx">Heavens Above Moon</a>
37  */
38 public class MoonCalcTest {
39
40     private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Europe/Amsterdam");
41     private static final Calendar FEB_27_2019 = MoonCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 1, 0, TIME_ZONE);
42     private static final double AMSTERDAM_LATITUDE = 52.367607;
43     private static final double AMSTERDAM_LONGITUDE = 4.8978293;
44
45     private static final int ACCURACY_IN_MILLIS = 5 * 60 * 1000;
46     private static final int ACCURACY_IN_KILOMETRES = 4;
47     private static final double ACCURACY_IN_DEGREE = 0.3;
48
49     private MoonCalc moonCalc;
50
51     @BeforeEach
52     public void init() {
53         moonCalc = new MoonCalc();
54     }
55
56     @Test
57     public void testGetMoonInfoForOldDate() {
58         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
59
60         assertNotNull(moon.getApogee());
61         assertNotNull(moon.getPerigee());
62
63         assertNotNull(moon.getDistance());
64         assertNotNull(moon.getEclipse());
65
66         assertNotNull(moon.getPhase());
67         assertNotNull(moon.getPosition());
68         assertNotNull(moon.getRise());
69         assertNotNull(moon.getSet());
70         assertNotNull(moon.getZodiac());
71
72         // for an old date the phase should not be calculated
73         assertNull(moon.getPhase().getName());
74     }
75
76     @Test
77     public void testGetMoonInfoForApogeeAccuracy() {
78         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
79
80         // expected result from haevens-above.com is 406,391 km @ 04 March 2019 12:27
81         assertEquals(406391, moon.getApogee().getDistance().doubleValue(), ACCURACY_IN_KILOMETRES);
82         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 4, 12, 27, TIME_ZONE).getTimeInMillis(),
83                 moon.getApogee().getDate().getTimeInMillis(), ACCURACY_IN_MILLIS);
84     }
85
86     @Test
87     public void testGetMoonInfoForPerigeeAccuracy() {
88         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
89
90         // expected result from haevens-above.com is 359,377 km @ 19 February 2019 20:44
91         assertEquals(359377, moon.getPerigee().getDistance().doubleValue(), ACCURACY_IN_KILOMETRES);
92
93         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 19, 20, 48, TIME_ZONE).getTimeInMillis(),
94                 moon.getPerigee().getDate().getTimeInMillis(), ACCURACY_IN_MILLIS);
95     }
96
97     @Test
98     public void testGetMoonInfoForRiseAccuracy() {
99         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
100
101         // expected result from haevens-above.com is 03:00
102         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 3, 0, TIME_ZONE).getTimeInMillis(),
103                 moon.getRise().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
104     }
105
106     @Test
107     public void testGetMoonInfoForSetAccuracy() {
108         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
109
110         // expected result from haevens-above.com is 11:35
111         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 11, 35, TIME_ZONE).getTimeInMillis(),
112                 moon.getSet().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
113     }
114
115     @Test
116     public void testGetMoonInfoForZodiac() {
117         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
118         moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
119
120         assertEquals(ZodiacSign.SAGITTARIUS, moon.getZodiac().getSign());
121     }
122
123     @Test
124     public void testGetMoonInfoForMoonPositionAccuracy() {
125         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
126         moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
127
128         // expected result from haevens-above.com is Azimuth: 100.5, altitude -17
129         assertEquals(100.5, moon.getPosition().getAzimuth().doubleValue(), ACCURACY_IN_DEGREE);
130         assertEquals(-17, moon.getPosition().getElevation().doubleValue(), ACCURACY_IN_DEGREE);
131     }
132
133     @Test
134     public void testGetMoonInfoForMoonDistanceAccuracy() {
135         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
136         moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
137
138         // expected result from haevens-above.com is 392612 km
139         assertEquals(392612, moon.getDistance().getDistance().doubleValue(), ACCURACY_IN_KILOMETRES);
140     }
141
142     @Test
143     public void testGetMoonInfoForMoonPhaseAccuracy() {
144         Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
145         moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
146
147         // New moon 06 March 2019 17:04
148         // First quarter 14 March 2019 11:27
149         // Full moon 21 March 2019 02:43
150         // Last quarter 28 March 2019 05:10
151         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 06, 17, 04, TIME_ZONE).getTimeInMillis(),
152                 moon.getPhase().getNew().getTimeInMillis(), ACCURACY_IN_MILLIS);
153         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 14, 11, 27, TIME_ZONE).getTimeInMillis(),
154                 moon.getPhase().getFirstQuarter().getTimeInMillis(), ACCURACY_IN_MILLIS);
155         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 21, 02, 43, TIME_ZONE).getTimeInMillis(),
156                 moon.getPhase().getFull().getTimeInMillis(), ACCURACY_IN_MILLIS);
157         assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 28, 05, 10, TIME_ZONE).getTimeInMillis(),
158                 moon.getPhase().getThirdQuarter().getTimeInMillis(), ACCURACY_IN_MILLIS);
159     }
160
161     /***
162      * Constructs a <code>GregorianCalendar</code> with the given date and time set
163      * for the provided time zone.
164      *
165      * @param year
166      *            the value used to set the <code>YEAR</code> calendar field in the
167      *            calendar.
168      * @param month
169      *            the value used to set the <code>MONTH</code> calendar field in the
170      *            calendar. Month value is 0-based. e.g., 0 for January.
171      * @param dayOfMonth
172      *            the value used to set the <code>DAY_OF_MONTH</code> calendar field
173      *            in the calendar.
174      * @param hourOfDay
175      *            the value used to set the <code>HOUR_OF_DAY</code> calendar field
176      *            in the calendar.
177      * @param minute
178      *            the value used to set the <code>MINUTE</code> calendar field in
179      *            the calendar.
180      * @param zone
181      *            the given time zone.
182      * @return
183      */
184     private static Calendar newCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, TimeZone zone) {
185         Calendar result = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute);
186         result.setTimeZone(zone);
187
188         return result;
189     }
190 }