From 664343ae9a6f4983b637a44fb0515d285f083f12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20Bergst=C3=B8l?= Date: Fri, 20 Sep 2024 09:28:14 +0200 Subject: [PATCH 1/2] Rewrite NorwegianDateUtil to use java.time java.util.Date and java.util.Calendar is old now and we don't want to use that any more. Breaking changes: We use ZonedDateTime in stead of Date to represent a date to check for working days. The list of holidays are now a NavigableSet and not a Date[]. Co-authored-by: tobiasgwaaler Co-authored-by: runeflobakk Co-authored-by: martin-jackson Co-authored-by: hhaga Co-authored-by: fredrbus --- pom.xml | 6 + .../bekk/bekkopen/date/NorwegianDateUtil.java | 259 +++++------------- .../bekkopen/date/NorwegianDateUtilTest.java | 202 ++++++++------ 3 files changed, 191 insertions(+), 276 deletions(-) diff --git a/pom.xml b/pom.xml index 4c04536..8201ff3 100644 --- a/pom.xml +++ b/pom.xml @@ -125,6 +125,12 @@ 2.2 test + + uk.co.probablyfine + java-8-matchers + 1.9 + test + org.hibernate.validator hibernate-validator diff --git a/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java b/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java index 343ef1d..7e6e2c5 100644 --- a/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java +++ b/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java @@ -26,19 +26,24 @@ * #L% */ -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZonedDateTime; +import java.util.Comparator; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; +import java.util.NavigableSet; import java.util.Set; +import java.util.TreeSet; +import java.util.stream.Stream; /** * Utility class for Norwegian dates. */ public class NorwegianDateUtil { - private static Map> holidays; + + private final static Map> holidays = new HashMap<>(); /** * Adds the given number of working days to the given date. A working day is @@ -60,19 +65,14 @@ public class NorwegianDateUtil { * The number of working days to add. * @return The new date. */ - public static Date addWorkingDaysToDate(Date date, int days) { - Calendar cal = dateToCalendar(date); - - for (int i = 0; i < days; i++) { - cal.add(Calendar.DATE, 1); - while (!isWorkingDay(cal)) { - cal.add(Calendar.DATE, 1); - } - } - - return cal.getTime(); + public static ZonedDateTime addWorkingDaysToDate(ZonedDateTime date, int days) { + return Stream.iterate(date, (d) -> d.plusDays(1)) + .filter(NorwegianDateUtil::isWorkingDay) + .limit(days + 1) + .max(Comparator.naturalOrder()) + .orElse(date); } - + /** * Will check if the given date is a working day. That is check if the given * date is a weekend day or a national holiday. @@ -81,8 +81,8 @@ public static Date addWorkingDaysToDate(Date date, int days) { * The date to check. * @return true if the given date is a working day, false otherwise. */ - public static boolean isWorkingDay(Date date) { - return isWorkingDay(dateToCalendar(date)); + public static boolean isWorkingDay(ZonedDateTime date) { + return date.getDayOfWeek() != DayOfWeek.SATURDAY && date.getDayOfWeek() != DayOfWeek.SUNDAY && !isHoliday(date); } /** @@ -92,24 +92,50 @@ public static boolean isWorkingDay(Date date) { * The Date to check. * @return true if holiday, false otherwise. */ - public static boolean isHoliday(Date date) { - return isHoliday(dateToCalendar(date)); + public static boolean isHoliday(ZonedDateTime date) { + final Set holidaySet = getHolidaySet(date.getYear()); + return holidaySet.contains(date.toLocalDate()); } - + /** - * Return a sorted array of holidays for a given year. + * Return a sorted set of holidays for a given year. * * @param year * The year to get holidays for. - * @return The array of holidays, sorted by date. + * @return The set of holidays, naturally sorted by date. */ - public static Date[] getHolidays(int year) { - Set days = getHolidaySet(year); - Date[] dates = days.toArray(new Date[days.size()]); - Arrays.sort(dates); - return dates; + public static NavigableSet getHolidays(int year) { + return getHolidaySet(year); } + /** + * Calculates easter day (sunday) by using Spencer Jones formula found here: + * Wikipedia - + * Påskeformelen + * + * @param year + * The year to calculate from. + * @return The LocalDate representing easter day for the given year. + */ + private static LocalDate getEasterDay(int year) { + int a = year % 19; + int b = year / 100; + int c = year % 100; + int d = b / 4; + int e = b % 4; + int f = (b + 8) / 25; + int g = (b - f + 1) / 3; + int h = ((19 * a) + b - d - g + 15) % 30; + int i = c / 4; + int k = c % 4; + int l = (32 + (2 * e) + (2 * i) - h - k) % 7; + int m = (a + (11 * h) + (22 * l)) / 451; + int n = (h + l - (7 * m) + 114) / 31; // This is the month number. + int p = (h + l - (7 * m) + 114) % 31; // This is the date minus one. + + return LocalDate.of(year, n, p + 1); + } + /** * Get a set of holidays for a given year. * @@ -117,189 +143,46 @@ public static Date[] getHolidays(int year) { * The year to get holidays for. * @return The set of dates. */ - private static Set getHolidaySet(int year) { - if (holidays == null) { - holidays = new HashMap<>(); - } + private static NavigableSet getHolidaySet(int year) { if (!holidays.containsKey(year)) { - Set yearSet = new HashSet<>(); + NavigableSet yearSet = new TreeSet<>(); // Add set holidays. - yearSet.add(getDate(1, Calendar.JANUARY, year)); - yearSet.add(getDate(1, Calendar.MAY, year)); - yearSet.add(getDate(17, Calendar.MAY, year)); - yearSet.add(getDate(25, Calendar.DECEMBER, year)); - yearSet.add(getDate(26, Calendar.DECEMBER, year)); + yearSet.add(LocalDate.of(year, Month.JANUARY, 1)); + yearSet.add(LocalDate.of(year, Month.MAY, 1)); + yearSet.add(LocalDate.of(year, Month.MAY, 17)); + yearSet.add(LocalDate.of(year, Month.DECEMBER, 25)); + yearSet.add(LocalDate.of(year, Month.DECEMBER, 26)); // Add movable holidays - based on easter day. - Calendar easterDay = dateToCalendar(getEasterDay(year)); + final LocalDate easterDay = getEasterDay(year); // Sunday before easter. - yearSet.add(rollGetDate(easterDay, -7)); + yearSet.add(easterDay.minusDays(7)); // Thursday before easter. - yearSet.add(rollGetDate(easterDay, -3)); + yearSet.add(easterDay.minusDays(3)); // Friday before easter. - yearSet.add(rollGetDate(easterDay, -2)); + yearSet.add(easterDay.minusDays(2)); // Easter day. - yearSet.add(easterDay.getTime()); + yearSet.add(easterDay); // Second easter day. - yearSet.add(rollGetDate(easterDay, 1)); + yearSet.add(easterDay.plusDays(1)); // "Kristi himmelfart" day. - yearSet.add(rollGetDate(easterDay, 39)); + yearSet.add(easterDay.plusDays(39)); // "Pinse" day. - yearSet.add(rollGetDate(easterDay, 49)); + yearSet.add(easterDay.plusDays(49)); // Second "Pinse" day. - yearSet.add(rollGetDate(easterDay, 50)); + yearSet.add(easterDay.plusDays(50)); holidays.put(year, yearSet); } return holidays.get(year); } - - /** - * Will check if the given date is a working day. That is check if the given - * date is a weekend day or a national holiday. - * - * @param cal - * The Calendar object representing the date. - * @return true if the given date is a working day, false otherwise. - */ - private static boolean isWorkingDay(Calendar cal) { - return cal.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && cal.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY - && !isHoliday(cal); - } - - /** - * Check if given Calendar object represents a holiday. - * - * @param cal - * The Calendar to check. - * @return true if holiday, false otherwise. - */ - private static boolean isHoliday(Calendar cal) { - int year = cal.get(Calendar.YEAR); - Set yearSet = getHolidaySet(year); - for (Object aYearSet : yearSet) { - Date date = (Date) aYearSet; - if (checkDate(cal, dateToCalendar(date))) { - return true; - } - } - return false; - } - - /** - * Calculates easter day (sunday) by using Spencer Jones formula found here: - * Wikipedia - - * Påskeformelen - * - * @param year - * The year to calculate from. - * @return The Calendar object representing easter day for the given year. - */ - private static Date getEasterDay(int year) { - int a = year % 19; - int b = year / 100; - int c = year % 100; - int d = b / 4; - int e = b % 4; - int f = (b + 8) / 25; - int g = (b - f + 1) / 3; - int h = ((19 * a) + b - d - g + 15) % 30; - int i = c / 4; - int k = c % 4; - int l = (32 + (2 * e) + (2 * i) - h - k) % 7; - int m = (a + (11 * h) + (22 * l)) / 451; - int n = (h + l - (7 * m) + 114) / 31; // This is the month number. - int p = (h + l - (7 * m) + 114) % 31; // This is the date minus one. - - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, n - 1); - cal.set(Calendar.DATE, p + 1); - - return cal.getTime(); - } - - /** - * Check if the given dates match on day and month. - * - * @param cal - * The Calendar representing the first date. - * @param other - * The Calendar representing the second date. - * @return true if they match, false otherwise. - */ - private static boolean checkDate(Calendar cal, Calendar other) { - return checkDate(cal, other.get(Calendar.DATE), other.get(Calendar.MONTH)); - } - - /** - * Check if the given date represents the given date and month. - * - * @param cal - * The Calendar object representing date to check. - * @param date - * The date. - * @param month - * The month. - * @return true if they match, false otherwise. - */ - private static boolean checkDate(Calendar cal, int date, int month) { - return cal.get(Calendar.DATE) == date && cal.get(Calendar.MONTH) == month; - } - - /** - * Convert the given Date object to a Calendar instance. - * - * @param date - * The Date object. - * @return The Calendar instance. - */ - private static Calendar dateToCalendar(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - return cal; - } - - /** - * Add the given number of days to the calendar and convert to Date. - * - * @param calendar - * The calendar to add to. - * @param days - * The number of days to add. - * @return The date object given by the modified calendar. - */ - private static Date rollGetDate(Calendar calendar, int days) { - Calendar easterSunday = (Calendar) calendar.clone(); - easterSunday.add(Calendar.DATE, days); - return easterSunday.getTime(); - } - - /** - * Get the date for the given values. - * - * @param day - * The day. - * @param month - * The month. - * @param year - * The year. - * @return The date represented by the given values. - */ - private static Date getDate(int day, int month, int year) { - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, year); - cal.set(Calendar.MONTH, month); - cal.set(Calendar.DATE, day); - return cal.getTime(); - } } diff --git a/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java b/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java index 6e6f32e..9bf038d 100644 --- a/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java +++ b/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java @@ -26,139 +26,165 @@ * #L% */ -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.NavigableSet; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; +import static uk.co.probablyfine.matchers.Java8Matchers.where; public class NorwegianDateUtilTest { - private static DateFormat FORMAT(){ - return new SimpleDateFormat("dd.MM.yyyy"); - } + + public static ZoneId NORGESONE = ZoneId.of("Europe/Oslo"); - @BeforeEach - public void setLocale() { - Locale.setDefault(new Locale("no", "NO")); + @Test + public void testAdd2DaysWithinSameWeek() { + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 18).atStartOfDay(NORGESONE); + + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 2); + + assertEquals(20, ny.getDayOfMonth()); } + @Test - public void testAdd2DaysWithinSameWeek() throws Exception { - Calendar cal = Calendar.getInstance(); - cal.setTime(NorwegianDateUtil.addWorkingDaysToDate(FORMAT().parse("21.03.2007"), 2)); + public void testAdd2DaysBeforeWeekend() { + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 20).atStartOfDay(NORGESONE); + + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 2); - assertEquals(23, cal.get(Calendar.DATE)); + assertEquals(24, ny.getDayOfMonth()); } + @Test - public void testAdd2DaysToLastDayOfMonth() throws Exception { - Calendar cal = Calendar.getInstance(); - cal.setTime(NorwegianDateUtil.addWorkingDaysToDate(FORMAT().parse("28.02.2007"), 2)); + void testAdd2DaysToLastDayOfMonth() { + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 30).atStartOfDay(NORGESONE); + + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 2); - assertEquals(2, cal.get(Calendar.DATE)); - assertEquals(Calendar.MARCH, cal.get(Calendar.MONTH)); + assertEquals(2, ny.getDayOfMonth()); + assertEquals(Month.OCTOBER, ny.getMonth()); } @Test - public void testAdd5DaysWithNoHolidays() throws Exception { - Calendar cal = Calendar.getInstance(); - cal.setTime(NorwegianDateUtil.addWorkingDaysToDate(FORMAT().parse("21.03.2007"), 5)); + void testAdd5DaysWithNoHolidays() { + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 30).atStartOfDay(NORGESONE); - assertEquals(28, cal.get(Calendar.DATE)); + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 5); + + assertEquals(7, ny.getDayOfMonth()); + assertEquals(Month.OCTOBER, ny.getMonth()); } @Test - public void testAdd5DaysBeforeEasterHoliday() throws Exception { - Calendar cal = Calendar.getInstance(); - cal.setTime(NorwegianDateUtil.addWorkingDaysToDate(FORMAT().parse("04.04.2007"), 5)); + void testAdd5DaysBeforeEasterHoliday() { + ZonedDateTime zonedDateTime = LocalDate.of(2025, 4, 11).atStartOfDay(NORGESONE); + + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 5); - assertEquals(16, cal.get(Calendar.DATE)); + assertEquals(23, ny.getDayOfMonth()); + assertEquals(Month.APRIL, ny.getMonth()); } @Test - public void testAdd5DaysBeforeNationalDay() throws Exception { - Calendar cal = Calendar.getInstance(); - cal.setTime(NorwegianDateUtil.addWorkingDaysToDate(FORMAT().parse("16.05.2007"), 5)); + void testAdd5DaysBeforeNationalDay() { + ZonedDateTime zonedDateTime = LocalDate.of(2007, 5, 16).atStartOfDay(NORGESONE); - assertEquals(24, cal.get(Calendar.DATE)); + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 5); + + assertEquals(24, ny.getDayOfMonth()); + assertEquals(Month.MAY, ny.getMonth()); } @Test - public void testAdd5DaysBeforeChristmas() throws Exception { - Calendar cal = Calendar.getInstance(); - cal.setTime(NorwegianDateUtil.addWorkingDaysToDate(FORMAT().parse("21.12.2007"), 5)); + void testAdd5DaysBeforeChristmas() { + ZonedDateTime zonedDateTime = LocalDate.of(2024, 12, 20).atStartOfDay(NORGESONE); + + ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 6); - assertEquals(2, cal.get(Calendar.DATE)); - assertEquals(Calendar.JANUARY, cal.get(Calendar.MONTH)); - assertEquals(2008, cal.get(Calendar.YEAR)); + assertEquals(2, ny.getDayOfMonth()); + assertEquals(Month.JANUARY, ny.getMonth()); + assertEquals(2025, ny.getYear()); } @Test - public void testWorkingDays() throws Exception { - assertFalse(NorwegianDateUtil.isWorkingDay(FORMAT().parse("25.03.2007")), "Sunday not working day"); - assertTrue(NorwegianDateUtil.isWorkingDay(FORMAT().parse("26.03.2007")), "Monday is working day"); - assertFalse(NorwegianDateUtil.isWorkingDay(FORMAT().parse("01.01.2007")), "New years day not working day"); - assertFalse(NorwegianDateUtil.isWorkingDay(FORMAT().parse("08.04.2007")), "Easter day not working day"); + public void testWorkingDays() { + assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2024, 9, 22).atStartOfDay(NORGESONE)), "Sunday not working day"); + assertTrue(NorwegianDateUtil.isWorkingDay(LocalDate.of(2024, 9, 16).atStartOfDay(NORGESONE)), "Monday is working day"); + assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2025, 1, 1).atStartOfDay(NORGESONE)), "New years day not working day"); + assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2007, 4, 8).atStartOfDay(NORGESONE)), "Easter day not working day"); } + @Test - public void testVariousNorwegianHolidays() throws Exception { + public void testVariousNorwegianHolidays() { // Set dates - checkHoliday("01.01.2007"); - checkHoliday("01.05.2007"); - checkHoliday("17.05.2007"); - checkHoliday("25.12.2007"); - checkHoliday("26.12.2007"); - - // Movable dates 2007 - checkHoliday("01.04.2007"); - checkHoliday("05.04.2007"); - checkHoliday("06.04.2007"); - checkHoliday("08.04.2007"); - checkHoliday("09.04.2007"); - checkHoliday("17.05.2007"); - checkHoliday("27.05.2007"); - checkHoliday("28.05.2007"); - - // Movable dates 2008 - checkHoliday("16.03.2008"); - checkHoliday("20.03.2008"); - checkHoliday("21.03.2008"); - checkHoliday("23.03.2008"); - checkHoliday("24.03.2008"); - checkHoliday("01.05.2008"); - checkHoliday("11.05.2008"); - checkHoliday("12.05.2008"); + checkHoliday(LocalDate.of(2007, 1, 1)); + checkHoliday(LocalDate.of(2007, 5, 1)); + checkHoliday(LocalDate.of(2007, 5, 17)); + checkHoliday(LocalDate.of(2007, 12, 25)); + checkHoliday(LocalDate.of(2007, 12, 26)); + + // Movable daLocalDate.of(2, 2, 2);tes 2007 + checkHoliday(LocalDate.of(2007, 4, 1)); + checkHoliday(LocalDate.of(2007, 4, 5)); + checkHoliday(LocalDate.of(2007, 4, 6)); + checkHoliday(LocalDate.of(2007, 4, 8)); + checkHoliday(LocalDate.of(2007, 4, 8)); + checkHoliday(LocalDate.of(2007, 5, 17)); + checkHoliday(LocalDate.of(2007, 5, 27)); + checkHoliday(LocalDate.of(2007, 5, 28)); + + // Movable daLocalDate.of(2, 2, 2);tes 2008 + checkHoliday(LocalDate.of(2008, 3, 16)); + checkHoliday(LocalDate.of(2008, 3, 20)); + checkHoliday(LocalDate.of(2008, 3, 21)); + checkHoliday(LocalDate.of(2008, 3, 23)); + checkHoliday(LocalDate.of(2008, 3, 24)); + checkHoliday(LocalDate.of(2008, 5, 1)); + checkHoliday(LocalDate.of(2008, 5, 11)); + checkHoliday(LocalDate.of(2008, 5, 12)); } + @Test public void testGetAllNorwegianHolidaysForYear() { - Date[] holidays = NorwegianDateUtil.getHolidays(2009); - assertEquals(13, holidays.length); - assertEquals("01.01.2009", FORMAT().format(holidays[0])); - assertEquals("05.04.2009", FORMAT().format(holidays[1])); - assertEquals("09.04.2009", FORMAT().format(holidays[2])); - assertEquals("10.04.2009", FORMAT().format(holidays[3])); - assertEquals("12.04.2009", FORMAT().format(holidays[4])); - assertEquals("13.04.2009", FORMAT().format(holidays[5])); - assertEquals("01.05.2009", FORMAT().format(holidays[6])); - assertEquals("17.05.2009", FORMAT().format(holidays[7])); - assertEquals("21.05.2009", FORMAT().format(holidays[8])); - assertEquals("31.05.2009", FORMAT().format(holidays[9])); - assertEquals("01.06.2009", FORMAT().format(holidays[10])); - assertEquals("25.12.2009", FORMAT().format(holidays[11])); - assertEquals("26.12.2009", FORMAT().format(holidays[12])); + NavigableSet holidays = NorwegianDateUtil.getHolidays(2009); + + assertEquals(13, holidays.size()); + + LinkedHashSet fasit = new LinkedHashSet<>(Arrays.asList( + LocalDate.of(2009, 1, 1), + LocalDate.of(2009, 4, 5), + LocalDate.of(2009, 4, 9), + LocalDate.of(2009, 4, 10), + LocalDate.of(2009, 4, 12), + LocalDate.of(2009, 4, 13), + LocalDate.of(2009, 5, 1), + LocalDate.of(2009, 5, 17), + LocalDate.of(2009, 5, 21), + LocalDate.of(2009, 5, 31), + LocalDate.of(2009, 6, 1), + LocalDate.of(2009, 12, 25), + LocalDate.of(2009, 12, 26) + )); + + assertEquals(fasit, holidays); + + } - private void checkHoliday(String date) throws ParseException { - assertTrue(NorwegianDateUtil.isHoliday(FORMAT().parse(date)), date); + private void checkHoliday(LocalDate date) { + assertThat(date.atStartOfDay(NORGESONE), where(NorwegianDateUtil::isHoliday)); } } From cde231a4cb4856b5d069abdf7d17d1eeb437f3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20Bergst=C3=B8l?= Date: Fri, 4 Oct 2024 18:14:44 +0200 Subject: [PATCH 2/2] Expose constants for Norwegian standard ZoneId Europe/Oslo --- .../bekk/bekkopen/date/NorwegianDateUtil.java | 4 +++ .../bekkopen/date/NorwegianDateUtilTest.java | 27 +++++++++---------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java b/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java index 7e6e2c5..ed18295 100644 --- a/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java +++ b/src/main/java/no/bekk/bekkopen/date/NorwegianDateUtil.java @@ -29,6 +29,7 @@ import java.time.DayOfWeek; import java.time.LocalDate; import java.time.Month; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Comparator; import java.util.HashMap; @@ -42,6 +43,9 @@ * Utility class for Norwegian dates. */ public class NorwegianDateUtil { + + public static final String ZONEID_EUROPE_OSLO = "Europe/Oslo"; + public static final ZoneId ZONE_NORWAY = ZoneId.of(ZONEID_EUROPE_OSLO); private final static Map> holidays = new HashMap<>(); diff --git a/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java b/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java index 9bf038d..74b4165 100644 --- a/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java +++ b/src/test/java/no/bekk/bekkopen/date/NorwegianDateUtilTest.java @@ -30,12 +30,12 @@ import java.time.LocalDate; import java.time.Month; -import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.NavigableSet; +import static no.bekk.bekkopen.date.NorwegianDateUtil.ZONE_NORWAY; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -44,11 +44,10 @@ public class NorwegianDateUtilTest { - public static ZoneId NORGESONE = ZoneId.of("Europe/Oslo"); @Test public void testAdd2DaysWithinSameWeek() { - ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 18).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 18).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 2); @@ -58,7 +57,7 @@ public void testAdd2DaysWithinSameWeek() { @Test public void testAdd2DaysBeforeWeekend() { - ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 20).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 20).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 2); @@ -68,7 +67,7 @@ public void testAdd2DaysBeforeWeekend() { @Test void testAdd2DaysToLastDayOfMonth() { - ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 30).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 30).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 2); @@ -78,7 +77,7 @@ void testAdd2DaysToLastDayOfMonth() { @Test void testAdd5DaysWithNoHolidays() { - ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 30).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2024, 9, 30).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 5); @@ -88,7 +87,7 @@ void testAdd5DaysWithNoHolidays() { @Test void testAdd5DaysBeforeEasterHoliday() { - ZonedDateTime zonedDateTime = LocalDate.of(2025, 4, 11).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2025, 4, 11).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 5); @@ -98,7 +97,7 @@ void testAdd5DaysBeforeEasterHoliday() { @Test void testAdd5DaysBeforeNationalDay() { - ZonedDateTime zonedDateTime = LocalDate.of(2007, 5, 16).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2007, 5, 16).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 5); @@ -108,7 +107,7 @@ void testAdd5DaysBeforeNationalDay() { @Test void testAdd5DaysBeforeChristmas() { - ZonedDateTime zonedDateTime = LocalDate.of(2024, 12, 20).atStartOfDay(NORGESONE); + ZonedDateTime zonedDateTime = LocalDate.of(2024, 12, 20).atStartOfDay(ZONE_NORWAY); ZonedDateTime ny = NorwegianDateUtil.addWorkingDaysToDate(zonedDateTime, 6); @@ -119,10 +118,10 @@ void testAdd5DaysBeforeChristmas() { @Test public void testWorkingDays() { - assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2024, 9, 22).atStartOfDay(NORGESONE)), "Sunday not working day"); - assertTrue(NorwegianDateUtil.isWorkingDay(LocalDate.of(2024, 9, 16).atStartOfDay(NORGESONE)), "Monday is working day"); - assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2025, 1, 1).atStartOfDay(NORGESONE)), "New years day not working day"); - assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2007, 4, 8).atStartOfDay(NORGESONE)), "Easter day not working day"); + assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2024, 9, 22).atStartOfDay(ZONE_NORWAY)), "Sunday not working day"); + assertTrue(NorwegianDateUtil.isWorkingDay(LocalDate.of(2024, 9, 16).atStartOfDay(ZONE_NORWAY)), "Monday is working day"); + assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2025, 1, 1).atStartOfDay(ZONE_NORWAY)), "New years day not working day"); + assertFalse(NorwegianDateUtil.isWorkingDay(LocalDate.of(2007, 4, 8).atStartOfDay(ZONE_NORWAY)), "Easter day not working day"); } @@ -185,6 +184,6 @@ public void testGetAllNorwegianHolidaysForYear() { } private void checkHoliday(LocalDate date) { - assertThat(date.atStartOfDay(NORGESONE), where(NorwegianDateUtil::isHoliday)); + assertThat(date.atStartOfDay(ZONE_NORWAY), where(NorwegianDateUtil::isHoliday)); } }