From 43514b851846147e16df4e88b272371ef5d6ae89 Mon Sep 17 00:00:00 2001 From: Hilbrand Bouwkamp Date: Tue, 22 Dec 2020 20:03:08 +0100 Subject: [PATCH] [astro] Fix for incorrect calculation of next season. (#9474) Signed-off-by: Hilbrand Bouwkamp --- .../binding/astro/internal/model/Season.java | 2 +- .../astro/internal/util/DateTimeUtils.java | 13 +++- .../internal/util/DateTimeUtilsTest.java | 77 +++++++++++++++++++ 3 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 bundles/org.openhab.binding.astro/src/test/java/org/openhab/binding/astro/internal/util/DateTimeUtilsTest.java diff --git a/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/model/Season.java b/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/model/Season.java index f173e385496ed..ed788eea5f396 100644 --- a/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/model/Season.java +++ b/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/model/Season.java @@ -109,7 +109,7 @@ public void setName(SeasonName name) { * Returns the next season. */ public Calendar getNextSeason() { - return DateTimeUtils.getNext(spring, summer, autumn, winter); + return DateTimeUtils.getNextFromToday(spring, summer, autumn, winter); } /** diff --git a/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/util/DateTimeUtils.java b/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/util/DateTimeUtils.java index c98db93b84e3a..fa916d5d762d3 100644 --- a/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/util/DateTimeUtils.java +++ b/bundles/org.openhab.binding.astro/src/main/java/org/openhab/binding/astro/internal/util/DateTimeUtils.java @@ -159,15 +159,22 @@ public static Date getDate(Calendar calendar) { /** * Returns the next Calendar from today. */ - public static Calendar getNext(Calendar... calendars) { - Calendar now = Calendar.getInstance(); + public static Calendar getNextFromToday(Calendar... calendars) { + return getNext(Calendar.getInstance(), calendars); + } + + static Calendar getNext(Calendar now, Calendar... calendars) { Calendar next = null; + Calendar firstSeasonOfYear = null; for (Calendar calendar : calendars) { + if (firstSeasonOfYear == null || calendar.before(firstSeasonOfYear)) { + firstSeasonOfYear = calendar; + } if (calendar.after(now) && (next == null || calendar.before(next))) { next = calendar; } } - return next; + return next == null ? firstSeasonOfYear : next; } /** diff --git a/bundles/org.openhab.binding.astro/src/test/java/org/openhab/binding/astro/internal/util/DateTimeUtilsTest.java b/bundles/org.openhab.binding.astro/src/test/java/org/openhab/binding/astro/internal/util/DateTimeUtilsTest.java new file mode 100644 index 0000000000000..b5a42183d42c7 --- /dev/null +++ b/bundles/org.openhab.binding.astro/src/test/java/org/openhab/binding/astro/internal/util/DateTimeUtilsTest.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2010-2020 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.astro.internal.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openhab.binding.astro.internal.calc.SeasonCalc; +import org.openhab.binding.astro.internal.model.Season; + +/** + * Test class for {@link DateTimeUtils}. + * + * @author Hilbrand Bouwkamp - Initial contribution + */ +public class DateTimeUtilsTest { + + private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Europe/Amsterdam"); + private static final Calendar JAN_20_2020 = newCalendar(2020, Calendar.JANUARY, 20, 1, 0, TIME_ZONE); + 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 double AMSTERDAM_LATITUDE = 52.367607; + private static final double SYDNEY_LATITUDE = -33.87; + + private SeasonCalc seasonCalc; + + @BeforeEach + public void init() { + seasonCalc = new SeasonCalc(); + } + + @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); + } + + @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); + } + + private void assertNextSeason(Calendar expectedSeason, Calendar date, Season season) { + assertEquals(expectedSeason, DateTimeUtils.getNext(date, season.getSpring(), season.getSummer(), + season.getAutumn(), season.getWinter())); + } + + private static Calendar newCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, TimeZone zone) { + Calendar result = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute); + result.setTimeZone(zone); + + return result; + } +}