Skip to content

Commit

Permalink
[astro] Fixed timeLeft calculation at the end of the year (openhab#11889
Browse files Browse the repository at this point in the history
)

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>
Signed-off-by: Michael Schmidt <mi.schmidt.83@gmail.com>
  • Loading branch information
Hilbrand authored and mischmidt83 committed Jan 9, 2022
1 parent 0ab68fb commit db77c35
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -127,9 +127,10 @@ public SeasonName getNextName() {
* 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,14 @@ static Calendar getNext(Calendar now, Calendar... calendars) {
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;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -47,20 +48,24 @@ public void init() {

@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
Expand All @@ -76,9 +81,11 @@ void testTruncate() {
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) {
Expand Down

0 comments on commit db77c35

Please sign in to comment.