diff --git a/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/internal/module/handler/EphemerisConditionHandler.java b/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/internal/module/handler/EphemerisConditionHandler.java index de87162bec9..6347632efa6 100644 --- a/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/internal/module/handler/EphemerisConditionHandler.java +++ b/bundles/org.openhab.core.automation/src/main/java/org/openhab/core/automation/internal/module/handler/EphemerisConditionHandler.java @@ -12,6 +12,7 @@ */ package org.openhab.core.automation.internal.module.handler; +import java.time.ZonedDateTime; import java.util.Map; import org.eclipse.jdt.annotation.NonNullByDefault; @@ -40,7 +41,7 @@ public class EphemerisConditionHandler extends BaseModuleHandler impl private final EphemerisManager ephemerisManager; private final @Nullable String dayset; - private final int offset; + private final ZonedDateTime target; public EphemerisConditionHandler(Condition condition, EphemerisManager ephemerisManager) { super(condition); @@ -49,7 +50,8 @@ public EphemerisConditionHandler(Condition condition, EphemerisManager ephemeris this.dayset = DAYSET_MODULE_TYPE_ID.equals(module.getTypeUID()) ? getValidStringConfigParameter(DAYSET, module.getConfiguration(), module.getId()) : null; - this.offset = getValidIntegerConfigParameter(OFFSET, module.getConfiguration(), module.getId()); + int offset = getValidIntegerConfigParameter(OFFSET, module.getConfiguration(), module.getId()); + target = ZonedDateTime.now().plusDays(offset); } private static int getValidIntegerConfigParameter(String parameter, Configuration config, String moduleId) { @@ -76,15 +78,15 @@ private static String getValidStringConfigParameter(String parameter, Configurat public boolean isSatisfied(Map inputs) { switch (module.getTypeUID()) { case HOLIDAY_MODULE_TYPE_ID: - return ephemerisManager.isBankHoliday(offset); + return ephemerisManager.isBankHoliday(target); case WEEKEND_MODULE_TYPE_ID: - return ephemerisManager.isWeekend(offset); + return ephemerisManager.isWeekend(target); case WEEKDAY_MODULE_TYPE_ID: - return !ephemerisManager.isWeekend(offset); + return !ephemerisManager.isWeekend(target); case DAYSET_MODULE_TYPE_ID: final String dayset = this.dayset; if (dayset != null) { - return ephemerisManager.isInDayset(dayset, offset); + return ephemerisManager.isInDayset(dayset, target); } break; } diff --git a/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/EphemerisManager.java b/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/EphemerisManager.java index 5ba545e74b5..7217851b746 100644 --- a/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/EphemerisManager.java +++ b/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/EphemerisManager.java @@ -13,6 +13,8 @@ package org.eclipse.smarthome.core.ephemeris; import java.io.FileNotFoundException; +import java.net.URL; +import java.time.ZonedDateTime; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -27,57 +29,145 @@ public interface EphemerisManager { /** - * Tests given day (related to today) status against configured weekend days + * Tests given day status against configured weekend days * - * @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday) + * @param date observed day * @return whether the day is on weekend */ - boolean isWeekend(int offset); + boolean isWeekend(ZonedDateTime date); /** - * Tests given day (related to today) status against configured dayset + * Tests given day status against configured dayset * * @param daysetName name of the requested dayset, without prefix - * @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday) - * @return whether the day is on weekend + * @param date observed day + * @return whether the day is in the dayset + */ + boolean isInDayset(String daysetName, ZonedDateTime date); + + /** + * Tests given day status + * + * @param date observed day + * @return whether the day is bank holiday or not */ - boolean isInDayset(String daysetName, int offset); + boolean isBankHoliday(ZonedDateTime date); /** - * Tests given day status against official bank holidays + * Tests given day status against given userfile * - * @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday) + * @param date observed day + * @param url bundle resource file containing holiday definitions * @return whether the day is bank holiday or not */ - boolean isBankHoliday(int offset); + boolean isBankHoliday(ZonedDateTime date, URL resource); /** * Tests given day status against given userfile * - * @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday) - * @param filename absolute or relative path to the file on local file system + * @param date observed day + * @param source absolute or relative path to the file on local file system * @return whether the day is bank holiday or not - * @throws FileNotFoundException if given file does not exist + * @throws FileNotFoundException + */ + boolean isBankHoliday(ZonedDateTime date, String filename) throws FileNotFoundException; + + /** + * Get given day name from given userfile + * + * @param date observed day + * @return name of the day or null if no corresponding entry */ - boolean isBankHoliday(int offset, String filename) throws FileNotFoundException; + @Nullable + String getBankHolidayName(ZonedDateTime date); /** - * Get given day bank holiday name + * Get given day name from given userfile * - * @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday) - * @return name of the bank holiday or null if no bank holiday + * @param date observed day + * @param url bundle resource file containing holiday definitions + * @return name of the day or null if no corresponding entry */ @Nullable - String getBankHolidayName(int offset); + String getBankHolidayName(ZonedDateTime date, URL resource); /** * Get given day name from given userfile * - * @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday) - * @param filename absolute or relative path to the file on local file system + * @param date observed day + * @param source absolute or relative path to the file on local file system * @return name of the day or null if no corresponding entry - * @throws FileNotFoundException if given file does not exist + * @throws FileNotFoundException + */ + @Nullable + String getBankHolidayName(ZonedDateTime date, String filename) throws FileNotFoundException; + + /** + * Gets the first next to come holiday in a 1 year time window + * + * @param startDate first day of the time window + * @return next coming holiday + */ + @Nullable + String getNextBankHoliday(ZonedDateTime startDate); + + /** + * Gets the first next to come holiday in a 1 year time window + * + * @param startDate first day of the time window + * @param url bundle resource file containing holiday definitions + * @return next coming holiday + */ + @Nullable + String getNextBankHoliday(ZonedDateTime startDate, URL resource); + + /** + * Gets the first next to come holiday in a 1 year time window + * + * @param startDate first day of the time window + * @param source absolute or relative path to the file on local file system + * @return next coming holiday + * @throws FileNotFoundException + */ + @Nullable + String getNextBankHoliday(ZonedDateTime startDate, String filename) throws FileNotFoundException; + + /** + * Gets the localized holiday description + * + * @param holidayName code of searched holiday + * @return localized holiday description */ @Nullable - String getBankHolidayName(int offset, String filename) throws FileNotFoundException; + String getHolidayDescription(@Nullable String holiday); + + /** + * Gets the number of days until searchedHoliday + * + * @param from first day of the time window + * @param searchedHoliday name of the searched holiday + * @return difference in days, -1 if not found + */ + long getDaysUntil(ZonedDateTime from, String searchedHoliday); + + /** + * Gets the number of days until searchedHoliday in user file + * + * @param from first day of the time window + * @param searchedHoliday name of the searched holiday + * @param url bundle resource file containing holiday definitions + * @return difference in days, -1 if not found + */ + long getDaysUntil(ZonedDateTime from, String searchedHoliday, URL resource); + + /** + * Gets the number of days until searchedHoliday in user file + * + * @param from first day of the time window + * @param searchedHoliday name of the searched holiday + * @param source absolute or relative path to the file on local file system + * @return difference in days, -1 if not found + * @throws FileNotFoundException + */ + long getDaysUntil(ZonedDateTime from, String searchedHoliday, String filename) throws FileNotFoundException; } diff --git a/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImpl.java b/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImpl.java index 80a87a27fe7..bd73ea3caf9 100644 --- a/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImpl.java +++ b/bundles/org.openhab.core.ephemeris/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImpl.java @@ -24,9 +24,11 @@ import java.time.LocalDate; import java.time.ZonedDateTime; import java.time.format.TextStyle; +import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -35,6 +37,7 @@ import java.util.Optional; import java.util.Properties; import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; @@ -57,6 +60,7 @@ import de.jollyday.HolidayManager; import de.jollyday.ManagerParameter; import de.jollyday.ManagerParameters; +import de.jollyday.util.ResourceUtil; /** * This service provides functionality around ephemeris services and is the central service to be used directly by @@ -92,6 +96,10 @@ public class EphemerisManagerImpl implements EphemerisManager, ConfigOptionProvi final Map> daysets = new HashMap<>(); private final Map holidayManagers = new HashMap<>(); private final List countryParameters = new ArrayList<>(); + /** + * Utility for accessing resources. + */ + private final ResourceUtil resourceUtil = new ResourceUtil(); private final LocaleProvider localeProvider; @@ -198,6 +206,18 @@ protected void modified(Map config) { return null; } + private URL getUrl(String filename) throws FileNotFoundException { + if (Files.exists(Paths.get(filename))) { + try { + return new URL("file:" + filename); + } catch (MalformedURLException e) { + throw new FileNotFoundException(e.getMessage()); + } + } else { + throw new FileNotFoundException(filename); + } + } + private HolidayManager getHolidayManager(Object managerKey) { return holidayManagers.computeIfAbsent(managerKey, key -> { final ManagerParameter parameters = managerKey.getClass() == String.class @@ -207,45 +227,64 @@ private HolidayManager getHolidayManager(Object managerKey) { }); } - private Optional getHoliday(ZonedDateTime date) { - HolidayManager manager = getHolidayManager(country); - LocalDate localDate = date.toLocalDate(); + private List getHolidays(ZonedDateTime from, int span, HolidayManager holidayManager) { + LocalDate fromDate = from.toLocalDate(); + LocalDate toDate = from.plusDays(span).toLocalDate(); - Set holidays = manager.getHolidays(localDate, localDate, countryParameters.toArray(new String[0])); - return holidays.isEmpty() ? Optional.empty() : Optional.of(holidays.iterator().next()); + Set days = holidayManager.getHolidays(fromDate, toDate, countryParameters.toArray(new String[0])); + List sortedHolidays = days.stream().sorted(Comparator.comparing(Holiday::getDate)) + .collect(Collectors.toList()); + return sortedHolidays; } - private boolean isBankHoliday(ZonedDateTime date) { - Optional holiday = getHoliday(date); - return holiday.isPresent(); + @Override + public long getDaysUntil(ZonedDateTime from, String searchedHoliday) { + List sortedHolidays = getHolidays(from, 366, getHolidayManager(country)); + Optional result = sortedHolidays.stream() + .filter(holiday -> searchedHoliday.equalsIgnoreCase(holiday.getPropertiesKey())).findFirst(); + return result.isPresent() ? from.toLocalDate().until(result.get().getDate(), ChronoUnit.DAYS) : -1; } @Override - public boolean isBankHoliday(int offset) { - return isBankHoliday(ZonedDateTime.now().plusDays(offset)); + public long getDaysUntil(ZonedDateTime from, String searchedHoliday, URL resource) { + List sortedHolidays = getHolidays(from, 366, getHolidayManager(resource)); + Optional result = sortedHolidays.stream() + .filter(holiday -> searchedHoliday.equalsIgnoreCase(holiday.getPropertiesKey())).findFirst(); + return result.isPresent() ? from.toLocalDate().until(result.get().getDate(), ChronoUnit.DAYS) : -1; } @Override - public boolean isBankHoliday(int offset, String filename) throws FileNotFoundException { - Optional holiday = getHolidayUserFile(ZonedDateTime.now().plusDays(offset), filename); - return holiday.isPresent(); + public long getDaysUntil(ZonedDateTime from, String searchedHoliday, String filename) throws FileNotFoundException { + return getDaysUntil(from, searchedHoliday, getUrl(filename)); + } + + private @Nullable String getFirstBankHolidayKey(ZonedDateTime from, int span, HolidayManager holidayManager) { + Optional holiday = getHolidays(from, span, holidayManager).stream().findFirst(); + return holiday.map(p -> p.getPropertiesKey()).orElse(null); } @Override - public boolean isWeekend(int offset) { - return isWeekend(ZonedDateTime.now().plusDays(offset)); + public boolean isBankHoliday(ZonedDateTime date) { + return !getHolidays(date, 0, getHolidayManager(country)).isEmpty(); } - private boolean isWeekend(ZonedDateTime date) { - return isInDayset(CONFIG_DAYSET_WEEKEND, date); + @Override + public boolean isBankHoliday(ZonedDateTime date, URL resource) { + return !getHolidays(date, 0, getHolidayManager(resource)).isEmpty(); } @Override - public boolean isInDayset(String daysetName, int offset) { - return isInDayset(daysetName, ZonedDateTime.now().plusDays(offset)); + public boolean isBankHoliday(ZonedDateTime date, String filename) throws FileNotFoundException { + return isBankHoliday(date, getUrl(filename)); + } + + @Override + public boolean isWeekend(ZonedDateTime date) { + return isInDayset(CONFIG_DAYSET_WEEKEND, date); } - private boolean isInDayset(String daysetName, ZonedDateTime date) { + @Override + public boolean isInDayset(String daysetName, ZonedDateTime date) { if (daysets.containsKey(daysetName)) { DayOfWeek dow = date.getDayOfWeek(); return daysets.get(daysetName).contains(dow); @@ -255,34 +294,34 @@ private boolean isInDayset(String daysetName, ZonedDateTime date) { } } - private String getBankHolidayName(ZonedDateTime date) { - Optional holiday = getHoliday(date); - return holiday.map(p -> p.getDescription(localeProvider.getLocale())).orElse(null); + @Override + public @Nullable String getBankHolidayName(ZonedDateTime date) { + return getFirstBankHolidayKey(date, 0, getHolidayManager(country)); } @Override - public @Nullable String getBankHolidayName(int offset) { - return getBankHolidayName(ZonedDateTime.now().plusDays(offset)); + public @Nullable String getBankHolidayName(ZonedDateTime date, URL resource) { + return getFirstBankHolidayKey(date, 0, getHolidayManager(resource)); } - private Optional getHolidayUserFile(ZonedDateTime date, String filename) throws FileNotFoundException { - if (Files.exists(Paths.get(filename))) { - try { - URL url = new URL("file:" + filename); - Set days = getHolidayManager(url).getHolidays(date.toLocalDate(), date.toLocalDate()); - return days.isEmpty() ? Optional.empty() : Optional.of(days.iterator().next().getPropertiesKey()); - } catch (MalformedURLException e) { - throw new FileNotFoundException(e.getMessage()); - } - } else { - throw new FileNotFoundException(); - } + @Override + public @Nullable String getBankHolidayName(ZonedDateTime date, String filename) throws FileNotFoundException { + return getBankHolidayName(date, getUrl(filename)); } @Override - public @Nullable String getBankHolidayName(int offset, String filename) throws FileNotFoundException { - Optional holiday = getHolidayUserFile(ZonedDateTime.now().plusDays(offset), filename); - return holiday.isPresent() ? holiday.get() : null; + public @Nullable String getNextBankHoliday(ZonedDateTime from) { + return getFirstBankHolidayKey(from, 365, getHolidayManager(country)); + } + + @Override + public @Nullable String getNextBankHoliday(ZonedDateTime from, URL resource) { + return getFirstBankHolidayKey(from, 365, getHolidayManager(resource)); + } + + @Override + public @Nullable String getNextBankHoliday(ZonedDateTime from, String filename) throws FileNotFoundException { + return getNextBankHoliday(from, getUrl(filename)); } private void addDayset(String setName, Iterable values) { @@ -359,4 +398,10 @@ private static String getValidPart(String part) { throw new IllegalArgumentException("Unable to parse property - token is empty."); } } + + @Override + public @Nullable String getHolidayDescription(@Nullable String holiday) { + return holiday != null ? resourceUtil.getHolidayDescription(localeProvider.getLocale(), holiday) : null; + } + } diff --git a/bundles/org.openhab.core.model.script/src/org/eclipse/smarthome/model/script/actions/Ephemeris.java b/bundles/org.openhab.core.model.script/src/org/eclipse/smarthome/model/script/actions/Ephemeris.java index 7f5d90d7704..a7a42698d1a 100644 --- a/bundles/org.openhab.core.model.script/src/org/eclipse/smarthome/model/script/actions/Ephemeris.java +++ b/bundles/org.openhab.core.model.script/src/org/eclipse/smarthome/model/script/actions/Ephemeris.java @@ -13,7 +13,9 @@ package org.eclipse.smarthome.model.script.actions; import java.io.FileNotFoundException; +import java.time.ZonedDateTime; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.smarthome.model.script.engine.action.ActionDoc; import org.eclipse.smarthome.model.script.internal.engine.action.EphemerisActionService; import org.slf4j.Logger; @@ -35,7 +37,12 @@ public static boolean isWeekend() { @ActionDoc(text = "checks if today plus or minus a given offset is a weekend day") public static boolean isWeekend(int offset) { - return EphemerisActionService.ephemerisManager.isWeekend(offset); + return isWeekend(ZonedDateTime.now().plusDays(offset)); + } + + @ActionDoc(text = "checks if a given day is a weekend day") + public static boolean isWeekend(ZonedDateTime day) { + return EphemerisActionService.ephemerisManager.isWeekend(day); } @ActionDoc(text = "checks if today is defined in a given dayset") @@ -45,7 +52,12 @@ public static boolean isInDayset(String daysetName) { @ActionDoc(text = "checks if today plus or minus a given offset is defined in a given dayset") public static boolean isInDayset(String daysetName, int offset) { - return EphemerisActionService.ephemerisManager.isInDayset(daysetName, offset); + return isInDayset(daysetName, ZonedDateTime.now().plusDays(offset)); + } + + @ActionDoc(text = "checks a given day is defined in a given dayset") + public static boolean isInDayset(String daysetName, ZonedDateTime day) { + return EphemerisActionService.ephemerisManager.isInDayset(daysetName, day); } @ActionDoc(text = "checks if today is bank holiday") @@ -55,13 +67,23 @@ public static boolean isBankHoliday() { @ActionDoc(text = "checks if today plus or minus a given offset is bank holiday") public static boolean isBankHoliday(int offset) { - return EphemerisActionService.ephemerisManager.isBankHoliday(offset); + return isBankHoliday(ZonedDateTime.now().plusDays(offset)); + } + + @ActionDoc(text = "checks a given day is bank holiday") + public static boolean isBankHoliday(ZonedDateTime day) { + return EphemerisActionService.ephemerisManager.isBankHoliday(day); } @ActionDoc(text = "checks if today plus or minus a given offset is bank holiday from a given userfile") public static boolean isBankHoliday(int offset, String filename) { + return isBankHoliday(ZonedDateTime.now().plusDays(offset)); + } + + @ActionDoc(text = "checks a given day is bank holiday from a given userfile") + public static boolean isBankHoliday(ZonedDateTime day, String filename) { try { - return EphemerisActionService.ephemerisManager.isBankHoliday(offset, filename); + return EphemerisActionService.ephemerisManager.isBankHoliday(day, filename); } catch (FileNotFoundException e) { LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage()); return false; @@ -69,28 +91,103 @@ public static boolean isBankHoliday(int offset, String filename) { } @ActionDoc(text = "get todays bank holiday name") - public static String getBankHolidayName() { + public static @Nullable String getBankHolidayName() { return getBankHolidayName(0); } @ActionDoc(text = "get bank holiday name for today plus or minus a given offset") - public static String getBankHolidayName(int offset) { - return EphemerisActionService.ephemerisManager.getBankHolidayName(offset); + public static @Nullable String getBankHolidayName(int offset) { + return getBankHolidayName(ZonedDateTime.now().plusDays(offset)); + } + + @ActionDoc(text = "get bank holiday name for a given day") + public static @Nullable String getBankHolidayName(ZonedDateTime day) { + return EphemerisActionService.ephemerisManager.getBankHolidayName(day); } @ActionDoc(text = "get holiday for today from a given userfile") - public static String getBankHolidayName(String filename) { + public static @Nullable String getBankHolidayName(String filename) { return getBankHolidayName(0, filename); } @ActionDoc(text = "get holiday for today plus or minus an offset from a given userfile") - public static String getBankHolidayName(int offset, String filename) { + public static @Nullable String getBankHolidayName(int offset, String filename) { + return getBankHolidayName(ZonedDateTime.now().plusDays(offset), filename); + } + + @ActionDoc(text = "get holiday for a given day from a given userfile") + public static @Nullable String getBankHolidayName(ZonedDateTime day, String filename) { try { - return EphemerisActionService.ephemerisManager.getBankHolidayName(offset, filename); + return EphemerisActionService.ephemerisManager.getBankHolidayName(day, filename); } catch (FileNotFoundException e) { LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage()); return null; } } -} \ No newline at end of file + @ActionDoc(text = "get next bank holiday") + public static @Nullable String getNextBankHoliday() { + return getNextBankHoliday(0); + } + + @ActionDoc(text = "get next bank holiday plus or minus an offset") + public static @Nullable String getNextBankHoliday(int offset) { + return getNextBankHoliday(ZonedDateTime.now().plusDays(offset)); + } + + @ActionDoc(text = "get next bank holiday holiday from a given day") + public static @Nullable String getNextBankHoliday(ZonedDateTime day) { + return EphemerisActionService.ephemerisManager.getNextBankHoliday(day); + } + + @ActionDoc(text = "get next bank holiday from a given userfile") + public static @Nullable String getNextBankHoliday(String filename) { + return getNextBankHoliday(0, filename); + } + + @ActionDoc(text = "get next bank holiday plus or minus an offset from a given userfile") + public static @Nullable String getNextBankHoliday(int offset, String filename) { + return getNextBankHoliday(ZonedDateTime.now().plusDays(offset), filename); + } + + @ActionDoc(text = "get next bank holiday a given day from a given userfilee") + public static @Nullable String getNextBankHoliday(ZonedDateTime day, String filename) { + try { + return EphemerisActionService.ephemerisManager.getNextBankHoliday(day, filename); + } catch (FileNotFoundException e) { + LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage()); + return null; + } + } + + @ActionDoc(text = "gets the localized description of a holiday key name") + public static @Nullable String getHolidayDescription(@Nullable String holiday) { + return EphemerisActionService.ephemerisManager.getHolidayDescription(holiday); + } + + @ActionDoc(text = "gets the number of days between today and a given holiday") + public static long getDaysUntil(String searchedHoliday) { + return getDaysUntil(ZonedDateTime.now(), searchedHoliday); + } + + @ActionDoc(text = "gets the number of days between today and a given holiday") + public static long getDaysUntil(ZonedDateTime day, String searchedHoliday) { + return EphemerisActionService.ephemerisManager.getDaysUntil(day, searchedHoliday); + } + + @ActionDoc(text = "gets the number of days between today and a given holiday from a given userfile") + public static long getDaysUntil(String searchedHoliday, String filename) { + return getDaysUntil(ZonedDateTime.now(), searchedHoliday, filename); + } + + @ActionDoc(text = "gets the number of days between a given day and a given holiday from a given userfile") + public static long getDaysUntil(ZonedDateTime day, String searchedHoliday, String filename) { + try { + return EphemerisActionService.ephemerisManager.getDaysUntil(day, searchedHoliday, filename); + } catch (FileNotFoundException e) { + LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage()); + return -1; + } + } + +} diff --git a/itests/org.openhab.core.ephemeris.tests/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImplOSGiTest.java b/itests/org.openhab.core.ephemeris.tests/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImplOSGiTest.java index de02a806965..b5b16dcc8c3 100644 --- a/itests/org.openhab.core.ephemeris.tests/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImplOSGiTest.java +++ b/itests/org.openhab.core.ephemeris.tests/src/main/java/org/eclipse/smarthome/core/ephemeris/internal/EphemerisManagerImplOSGiTest.java @@ -16,7 +16,10 @@ import static org.junit.Assert.*; import java.net.URI; +import java.net.URL; import java.time.DayOfWeek; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.AbstractMap.SimpleEntry; import java.util.Collection; import java.util.Collections; @@ -41,7 +44,7 @@ */ @NonNullByDefault public class EphemerisManagerImplOSGiTest extends JavaOSGiTest { - + private static final String INTERNAL_DAYSET = "internal"; private static final URI CONFIG_URI = URI.create("system:ephemeris"); private static final String COUNTRY_AUSTRALIA_KEY = "au"; private static final String COUNTRY_AUSTRALIA_NAME = "Australia"; @@ -233,4 +236,81 @@ public void testConfigOptionProviderCitiesTasmania() { assertFalse(options.isEmpty()); assertEquals(ephemerisManager.cities.get(REGION_TASMANIA_KEY), options); } + + @Test + public void testWeekends() { + ZonedDateTime monday = ZonedDateTime.of(2019, 10, 28, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + ZonedDateTime sunday = ZonedDateTime.of(2019, 10, 27, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + ephemerisManager.modified(Collections.singletonMap(CONFIG_DAYSET_PREFIX + INTERNAL_DAYSET, + Stream.of("Monday", "Tuesday").collect(Collectors.toList()))); + assertEquals(true, ephemerisManager.isWeekend(sunday)); + assertEquals(false, ephemerisManager.isWeekend(monday)); + assertEquals(true, ephemerisManager.isInDayset(INTERNAL_DAYSET, monday)); + assertEquals(false, ephemerisManager.isInDayset(INTERNAL_DAYSET, sunday)); + } + + @Test + public void testIsBankHoliday() { + ZonedDateTime newyearsday = ZonedDateTime.of(2019, 01, 01, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + ZonedDateTime secondday = ZonedDateTime.of(2019, 01, 02, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + + boolean vacation = ephemerisManager.isBankHoliday(newyearsday); + assertEquals(true, vacation); + + vacation = ephemerisManager.isBankHoliday(secondday); + assertEquals(false, vacation); + } + + @Test + public void testGetBankHoliday() { + ZonedDateTime theDay = ZonedDateTime.of(2019, 01, 01, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + + boolean vacation = ephemerisManager.isBankHoliday(theDay); + assertEquals(true, vacation); + + String code = ephemerisManager.getBankHolidayName(theDay); + assertEquals("NEW_YEAR", code); + + String name = ephemerisManager.getHolidayDescription(code); + assertNotNull(name); + } + + @Test + public void testNextBankHoliday() { + ZonedDateTime today = ZonedDateTime.of(2019, 12, 28, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + long delay = ephemerisManager.getDaysUntil(today, "NONEXISTING"); + assertEquals(-1, delay); + + String next = ephemerisManager.getNextBankHoliday(today); + assertEquals("NEW_YEAR", next); + if (next != null) { + String description = ephemerisManager.getHolidayDescription(next); + assertNotNull(description); + + delay = ephemerisManager.getDaysUntil(today, next); + assertEquals(4, delay); + } + + } + + @Test + public void testUserFile() { + URL url = bundleContext.getBundle().getResource("events.xml"); + + ZonedDateTime today = ZonedDateTime.of(2019, 10, 28, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + ZonedDateTime theDay = ZonedDateTime.of(2019, 10, 31, 0, 0, 0, 0, ZoneId.of("Europe/Paris")); + + boolean vacation = ephemerisManager.isBankHoliday(theDay, url); + assertEquals(true, vacation); + + long delay = ephemerisManager.getDaysUntil(today, "Halloween", url); + assertEquals(3, delay); + + String next = ephemerisManager.getNextBankHoliday(today, url); + assertEquals("Halloween", next); + + String result = ephemerisManager.getBankHolidayName(theDay, url); + assertEquals("Halloween", result); + } + } diff --git a/itests/org.openhab.core.ephemeris.tests/src/main/resources/events.xml b/itests/org.openhab.core.ephemeris.tests/src/main/resources/events.xml new file mode 100644 index 00000000000..f53282ef5e7 --- /dev/null +++ b/itests/org.openhab.core.ephemeris.tests/src/main/resources/events.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + +