[astro] Fixed timeLeft calculation at the end of the year (#11889)

Season timeleft calculated the wrong time at the end of the year, because the seasons it measures the time with are the seasons within the same year.
So for times at the end of the year it computed against the season at the beginning of the year, resulting in negative number of days.
Also changed the time of timeLeft to actual days instead of quantity unit days.
Because with the milliseconds internal resolution it will generate events each and every time this channel is updated as milliseconds change often.

Signed-off-by: Hilbrand Bouwkamp <hilbrand@h72.nl>
This commit is contained in:
Hilbrand Bouwkamp 2021-12-30 13:49:43 +01:00 committed by GitHub
parent 50560f7b5b
commit 253f36abbf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 20 deletions

View File

@ -12,8 +12,8 @@
*/
package org.openhab.binding.astro.internal.model;
import static org.openhab.core.library.unit.MetricPrefix.MILLI;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Calendar;
import javax.measure.quantity.Time;
@ -127,9 +127,10 @@ public class Season {
* Returns the time left for current season
*/
public QuantityType<Time> getTimeLeft() {
Calendar now = Calendar.getInstance();
Calendar next = getNextSeason();
return new QuantityType<>(next.getTimeInMillis() - now.getTimeInMillis(), MILLI(Units.SECOND))
.toUnit(Units.DAY);
final Calendar now = Calendar.getInstance();
final Calendar next = getNextSeason();
final Duration timeLeft = Duration.of(next.getTimeInMillis() - now.getTimeInMillis(), ChronoUnit.MILLIS);
return new QuantityType<>(timeLeft.toDays(), Units.DAY);
}
}

View File

@ -192,7 +192,14 @@ public class DateTimeUtils {
next = calendar;
}
}
return next == null ? firstSeasonOfYear : next;
if (next == null) {
final Calendar nextYearSeason = (Calendar) firstSeasonOfYear.clone();
nextYearSeason.add(Calendar.YEAR, 1);
return nextYearSeason;
} else {
return next;
}
}
/**

View File

@ -35,6 +35,7 @@ public class DateTimeUtilsTest {
private static final Calendar MAY_20_2020 = newCalendar(2020, Calendar.MAY, 20, 1, 0, TIME_ZONE);
private static final Calendar SEPT_20_2020 = newCalendar(2020, Calendar.SEPTEMBER, 20, 1, 0, TIME_ZONE);
private static final Calendar DEC_10_2020 = newCalendar(2020, Calendar.DECEMBER, 1, 1, 0, TIME_ZONE);
private static final Calendar DEC_10_2021 = newCalendar(2021, Calendar.DECEMBER, 1, 1, 0, TIME_ZONE);
private static final double AMSTERDAM_LATITUDE = 52.367607;
private static final double SYDNEY_LATITUDE = -33.87;
@ -47,20 +48,24 @@ public class DateTimeUtilsTest {
@Test
public void testGetSeasonAmsterdam() {
Season season = seasonCalc.getSeason(DEC_10_2020, AMSTERDAM_LATITUDE, true);
assertNextSeason(season.getSpring(), JAN_20_2020, season);
assertNextSeason(season.getSummer(), MAY_20_2020, season);
assertNextSeason(season.getWinter(), SEPT_20_2020, season);
assertNextSeason(season.getSpring(), DEC_10_2020, season);
final Season season = seasonCalc.getSeason(DEC_10_2020, AMSTERDAM_LATITUDE, true);
assertNextSeason(season.getSpring(), 2020, JAN_20_2020, season);
assertNextSeason(season.getSummer(), 2020, MAY_20_2020, season);
assertNextSeason(season.getWinter(), 2020, SEPT_20_2020, season);
assertNextSeason(seasonCalc.getSeason(DEC_10_2021, AMSTERDAM_LATITUDE, true).getSpring(), 2021, DEC_10_2020,
season);
}
@Test
public void testGetSeasonSydney() {
Season season = seasonCalc.getSeason(DEC_10_2020, SYDNEY_LATITUDE, true);
assertNextSeason(season.getAutumn(), JAN_20_2020, season);
assertNextSeason(season.getWinter(), MAY_20_2020, season);
assertNextSeason(season.getSummer(), SEPT_20_2020, season);
assertNextSeason(season.getAutumn(), DEC_10_2020, season);
final Season season = seasonCalc.getSeason(DEC_10_2020, SYDNEY_LATITUDE, true);
assertNextSeason(season.getAutumn(), 2020, JAN_20_2020, season);
assertNextSeason(season.getWinter(), 2020, MAY_20_2020, season);
assertNextSeason(season.getSummer(), 2020, SEPT_20_2020, season);
assertNextSeason(seasonCalc.getSeason(DEC_10_2021, SYDNEY_LATITUDE, true).getAutumn(), 2021, DEC_10_2020,
season);
}
@Test
@ -76,9 +81,11 @@ public class DateTimeUtilsTest {
assertEquals(endOfDay, target2);
}
private void assertNextSeason(Calendar expectedSeason, Calendar date, Season season) {
assertEquals(expectedSeason, DateTimeUtils.getNext(date, season.getSpring(), season.getSummer(),
season.getAutumn(), season.getWinter()));
private static void assertNextSeason(Calendar expectedSeason, int expectedYear, Calendar date, Season season) {
final Calendar nextSeason = DateTimeUtils.getNext(date, season.getSpring(), season.getSummer(),
season.getAutumn(), season.getWinter());
assertEquals(expectedSeason, nextSeason, "Should return the expected season name.");
assertEquals(expectedYear, nextSeason.get(Calendar.YEAR), "Should return the year matching the next season.");
}
private static Calendar newCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, TimeZone zone) {