From bf5eaa8dce158ef821935ef34687a0fbd19ce9bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eivind=20Bergst=C3=B8l?= <>
Date: Thu, 19 Sep 2024 23:45:56 +0200
Subject: [PATCH 1/7] Update some dev dependendencies
---
pom.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index 859150c..e1b6693 100644
--- a/pom.xml
+++ b/pom.xml
@@ -116,7 +116,7 @@
org.junit.jupiter
junit-jupiter-api
- 5.9.0
+ 5.11.0
test
@@ -266,8 +266,8 @@
- 1.8
- 1.8
+ 8
+ 8
UTF-8
From b84a964c2e348c9f3d78fceb3917ef33f069648e 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 2/7] 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 e1b6693..7f695f9 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 288a1a3d5a9451404a058cfdafc10ce174e31342 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 3/7] 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));
}
}
From d118d24c3ad679bd55386fe67148a62742c07555 Mon Sep 17 00:00:00 2001
From: Martin Jackson
Date: Wed, 22 Oct 2025 19:24:08 +0200
Subject: [PATCH 4/7] =?UTF-8?q?Skriv=20om=20no.bekk.bekkopen.person=20til?=
=?UTF-8?q?=20=C3=A5=20bruke=20java.time?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Breaking change: Du må erstatte java.util.Date med java.time.LocalDate.
Gjorde i tillegg en liten endring i Person::getFodselsDato slik at
LocalDate-en som returneres har riktig århundre. Beregning av
fødselsdato fra fødselsnummer blir riktignok deprecated i pull requesten
nedenfor, men metoden får vel leve en liten stund til.
https://github.com/bekkopen/NoCommons/pull/74
---
.../person/FodselsnummerCalculator.java | 46 ++++++++-----------
.../java/no/bekk/bekkopen/person/Person.java | 12 ++---
.../person/FodselsnummerCalculatorTest.java | 33 ++++++-------
.../no/bekk/bekkopen/person/PersonTest.java | 27 ++++-------
.../SyntheticFodselsnummerCalculatorTest.java | 14 ++----
.../FodselsnummerAnnotationTest.java | 5 +-
6 files changed, 50 insertions(+), 87 deletions(-)
diff --git a/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java b/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java
index 1d11774..1920e8e 100644
--- a/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java
+++ b/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java
@@ -26,12 +26,10 @@
* #L%
*/
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.Collections;
-import java.util.Date;
import java.util.Iterator;
import java.util.List;
@@ -54,8 +52,7 @@ private FodselsnummerCalculator() {
* @param kjonn kjønn
* @return liste med fødselsnummer
*/
- @Deprecated
- public static List getFodselsnummerForDateAndGender(Date date, KJONN kjonn) {
+ public static List getFodselsnummerForDateAndGender(LocalDate date, KJONN kjonn) {
List result = getManyFodselsnummerForDate(date);
splitByGender(kjonn, result);
return result;
@@ -66,7 +63,7 @@ public static List getFodselsnummerForDateAndGender(Date date, KJ
* @param date en dato
* @return et fødselsnummer
*/
- public static Fodselsnummer getFodselsnummerForDate(Date date){
+ public static Fodselsnummer getFodselsnummerForDate(LocalDate date) {
List fodselsnummerList = getManyFodselsnummerForDate(date);
Collections.shuffle(fodselsnummerList);
return fodselsnummerList.get(0);
@@ -78,14 +75,13 @@ public static Fodselsnummer getFodselsnummerForDate(Date date){
* @param date The Date instance
* @return A List with Fodelsnummer instances
*/
-
- public static List getManyDNumberFodselsnummerForDate(Date date) {
+ public static List getManyDNumberFodselsnummerForDate(LocalDate date) {
if (date == null) {
throw new IllegalArgumentException();
}
- DateFormat df = new SimpleDateFormat("ddMMyy");
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMyy");
String centuryString = getCentury(date);
- String dateString = df.format(date);
+ String dateString = dtf.format(date);
dateString = Character.toChars(dateString.charAt(0) + 4)[0] +
dateString.substring(1);
return generateFodselsnummerForDate(dateString, centuryString);
@@ -97,14 +93,13 @@ public static List getManyDNumberFodselsnummerForDate(Date date)
* @param date The Date instance
* @return A List with Fodelsnummer instances
*/
-
- public static List getManySyntheticFodselsnummerForDate(Date date) {
+ public static List getManySyntheticFodselsnummerForDate(LocalDate date) {
if (date == null) {
throw new IllegalArgumentException();
}
- DateFormat df = new SimpleDateFormat("ddMMyy");
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMyy");
String centuryString = getCentury(date);
- String dateString = df.format(date);
+ String dateString = dtf.format(date);
dateString = dateString.substring(0, 2) +
Character.toChars(dateString.charAt(2) + 8)[0] +
dateString.substring(3);
@@ -117,14 +112,13 @@ public static List getManySyntheticFodselsnummerForDate(Date date
* @param date The Date instance
* @return A List with Fodelsnummer instances
*/
-
- public static List getManySyntheticDNumberFodselsnummerForDate(Date date) {
+ public static List getManySyntheticDNumberFodselsnummerForDate(LocalDate date) {
if (date == null) {
throw new IllegalArgumentException();
}
- DateFormat df = new SimpleDateFormat("ddMMyy");
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMyy");
String centuryString = getCentury(date);
- String dateString = df.format(date);
+ String dateString = dtf.format(date);
dateString = Character.toChars(dateString.charAt(0) + 4)[0] +
dateString.substring(1, 2) +
Character.toChars(dateString.charAt(2) + 8)[0] +
@@ -138,14 +132,13 @@ public static List getManySyntheticDNumberFodselsnummerForDate(Da
* @param date The Date instance
* @return A List with Fodelsnummer instances
*/
-
- public static List getManyFodselsnummerForDate(Date date) {
+ public static List getManyFodselsnummerForDate(LocalDate date) {
if (date == null) {
throw new IllegalArgumentException();
}
- DateFormat df = new SimpleDateFormat("ddMMyy");
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMyy");
String centuryString = getCentury(date);
- String dateString = df.format(date);
+ String dateString = dtf.format(date);
return generateFodselsnummerForDate(dateString, centuryString);
}
@@ -178,11 +171,8 @@ private static List generateFodselsnummerForDate(String dateStrin
return result;
}
- private static String getCentury(Date date) {
- Calendar c = Calendar.getInstance();
- c.setTime(date);
- int year = c.get(Calendar.YEAR);
- return Integer.toString(year).substring(0, 2);
+ private static String getCentury(LocalDate date) {
+ return Integer.toString(date.getYear()).substring(0, 2);
}
private static void splitByGender(KJONN kjonn, List result) {
diff --git a/src/main/java/no/bekk/bekkopen/person/Person.java b/src/main/java/no/bekk/bekkopen/person/Person.java
index 57b26ee..31960b4 100644
--- a/src/main/java/no/bekk/bekkopen/person/Person.java
+++ b/src/main/java/no/bekk/bekkopen/person/Person.java
@@ -26,14 +26,12 @@
* #L%
*/
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
public class Person {
- private final static DateFormat fDatoFormat = new SimpleDateFormat("ddMMyy");
+ private static final DateTimeFormatter fDatoFormat = DateTimeFormatter.ofPattern("ddMMyyyy");
private final Navn navn;
private final Fodselsnummer fodselsnummer;
@@ -67,8 +65,8 @@ public String getFodselsdatoAsString() {
return this.fodselsnummer.getDateOfBirth();
}
- public Date getFodselsdato() throws ParseException {
- return fDatoFormat.parse(this.fodselsnummer.getDateOfBirth());
+ public LocalDate getFodselsdato() {
+ return LocalDate.parse(this.fodselsnummer.getDateAndMonth() + this.fodselsnummer.getBirthYear(), fDatoFormat);
}
public String getPersonnummer() {
diff --git a/src/test/java/no/bekk/bekkopen/person/FodselsnummerCalculatorTest.java b/src/test/java/no/bekk/bekkopen/person/FodselsnummerCalculatorTest.java
index a297d25..4865bbd 100644
--- a/src/test/java/no/bekk/bekkopen/person/FodselsnummerCalculatorTest.java
+++ b/src/test/java/no/bekk/bekkopen/person/FodselsnummerCalculatorTest.java
@@ -26,13 +26,12 @@
* #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.Date;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.format.DateTimeFormatter;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -41,14 +40,8 @@
public class FodselsnummerCalculatorTest {
- private DateFormat df = null;
- private Date date = null;
-
- @BeforeEach
- public void setUpDate() throws Exception {
- df = new SimpleDateFormat("ddMMyyyy");
- date = df.parse("09062006");
- }
+ private final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("ddMMyyyy");
+ private LocalDate date = LocalDate.of(2006, Month.JUNE, 9);
@Test
public void testGetFodselsnummerForDate() {
@@ -87,9 +80,9 @@ public void testThatAtLeastOneDNumberIsGenerated() {
}
@Test
- public void testThatAtLeastOneDNumberIsGeneratedsas() throws ParseException {
- assertEquals(82, FodselsnummerCalculator.getManyDNumberFodselsnummerForDate(df.parse("06061878")).size());
- assertEquals(164, FodselsnummerCalculator.getManyDNumberFodselsnummerForDate(df.parse("12101921")).size());
+ public void testThatAtLeastOneDNumberIsGeneratedsas() {
+ assertEquals(82, FodselsnummerCalculator.getManyDNumberFodselsnummerForDate(LocalDate.parse("06061878", dtf)).size());
+ assertEquals(164, FodselsnummerCalculator.getManyDNumberFodselsnummerForDate(LocalDate.parse("12101921", dtf)).size());
}
@Test
@@ -107,22 +100,22 @@ public void testThatAllGeneratedDNumbersAreDNumbers() {
}
@Test
- public void testInvalidDateTooEarly() throws ParseException {
- date = df.parse("09091853");
+ public void testInvalidDateTooEarly() {
+ date = LocalDate.parse("09091853", dtf);
List options = FodselsnummerCalculator.getManyFodselsnummerForDate(date);
assertEquals(0, options.size());
}
@Test
- public void testInvalidDateTooLate() throws ParseException {
- date = df.parse("09092040");
+ public void testInvalidDateTooLate() {
+ date = LocalDate.parse("09092040", dtf);
List options = FodselsnummerCalculator.getManyFodselsnummerForDate(date);
assertEquals(0, options.size());
}
@Test
public void testOneFodselsnummer() throws ParseException {
- date = df.parse("01121980");
+ date = LocalDate.parse("01121980", dtf);
Fodselsnummer fodselsnummer = FodselsnummerCalculator.getFodselsnummerForDate(date);
assertTrue(FodselsnummerValidator.isValid(fodselsnummer.toString()));
}
diff --git a/src/test/java/no/bekk/bekkopen/person/PersonTest.java b/src/test/java/no/bekk/bekkopen/person/PersonTest.java
index 14ca255..0308074 100644
--- a/src/test/java/no/bekk/bekkopen/person/PersonTest.java
+++ b/src/test/java/no/bekk/bekkopen/person/PersonTest.java
@@ -26,15 +26,12 @@
* #L%
*/
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.util.Calendar;
-import java.util.Date;
+import java.time.LocalDate;
+import java.time.Month;
+import java.time.format.DateTimeFormatter;
import java.util.List;
-import java.util.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -43,17 +40,9 @@
public class PersonTest {
- private Calendar kalender;
-
- @BeforeEach
- public void initialiserKalender() {
- kalender = Calendar.getInstance();
- }
-
@Test
- public void lagMann() throws ParseException {
- kalender.set(1973, Calendar.DECEMBER, 10);
- Date fodselsdato = kalender.getTime();
+ public void lagMann() {
+ LocalDate fodselsdato = LocalDate.of(1973, Month.DECEMBER, 10);
List fodselsnumre = FodselsnummerCalculator.getFodselsnummerForDateAndGender(fodselsdato,
KJONN.MANN);
Fodselsnummer fodselsnummer = fodselsnumre.get(0);
@@ -80,9 +69,9 @@ public void lagMann() throws ParseException {
Navn pNavn = person.getNavn();
NavnGeneratorTest.assertGyldigNavn(pNavn);
- Date pFodselsdato = person.getFodselsdato();
- DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("no", "NO"));
- assertEquals(df.format(fodselsdato), df.format(pFodselsdato));
+ LocalDate pFodselsdato = person.getFodselsdato();
+ DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd.MM.yyyy");
+ assertEquals(dtf.format(fodselsdato), dtf.format(pFodselsdato));
String pFodselsdatoString = person.getFodselsdatoAsString();
assertEquals("101273", pFodselsdatoString);
diff --git a/src/test/java/no/bekk/bekkopen/person/SyntheticFodselsnummerCalculatorTest.java b/src/test/java/no/bekk/bekkopen/person/SyntheticFodselsnummerCalculatorTest.java
index 42d1705..2c87a9c 100644
--- a/src/test/java/no/bekk/bekkopen/person/SyntheticFodselsnummerCalculatorTest.java
+++ b/src/test/java/no/bekk/bekkopen/person/SyntheticFodselsnummerCalculatorTest.java
@@ -28,18 +28,16 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Date;
+import java.time.LocalDate;
+import java.time.Month;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SyntheticFodselsnummerCalculatorTest {
- private Date date = null;
+ private LocalDate date = LocalDate.of(2006, Month.JUNE, 9);
@BeforeAll
public static void setup() {
@@ -51,12 +49,6 @@ public static void teardown() {
FodselsnummerValidator.ALLOW_SYNTHETIC_NUMBERS = false;
}
- @BeforeEach
- public void setUpDate() throws Exception {
- DateFormat df = new SimpleDateFormat("ddMMyyyy");
- date = df.parse("09062006");
- }
-
@Test
public void testThatAllGeneratedSyntheticDNumbersAreValid() {
for (Fodselsnummer fnr : FodselsnummerCalculator.getManySyntheticDNumberFodselsnummerForDate(date)) {
diff --git a/src/test/java/no/bekk/bekkopen/person/annotation/FodselsnummerAnnotationTest.java b/src/test/java/no/bekk/bekkopen/person/annotation/FodselsnummerAnnotationTest.java
index 4b3ac8e..9dca296 100644
--- a/src/test/java/no/bekk/bekkopen/person/annotation/FodselsnummerAnnotationTest.java
+++ b/src/test/java/no/bekk/bekkopen/person/annotation/FodselsnummerAnnotationTest.java
@@ -34,7 +34,8 @@
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
-import java.util.Date;
+
+import java.time.LocalDate;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -69,7 +70,7 @@ public void should_accept_null_values(){
@Test
public void should_validate_valid_fodselsnummer(){
- Person k = new Person(FodselsnummerCalculator.getFodselsnummerForDate(new Date()).toString());
+ Person k = new Person(FodselsnummerCalculator.getFodselsnummerForDate(LocalDate.now()).toString());
Set> violations = validator.validate(k);
From b3c901b5dc9784b0952e76dbada1f74df8c50138 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eivind=20Bergst=C3=B8l?=
Date: Thu, 24 Sep 2026 15:21:21 +0200
Subject: [PATCH 5/7] =?UTF-8?q?Fjern=20kj=C3=B8nn=20fra=20Fodselsnummer?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Kjønn vil slutte å være et konsept i 2032 i sammenheng med
fødselsnummer. Vi forbereder oss allerede nå ved å ta vekk konseptet
i god tid.
Siden kjønn forsvinner fra fodselsnummer har vi ingen måte
i Person-klassen å identifisere om det er mannsnavn eller kvinnenavn.
jeg fjerner derfor enkelt og greit denne funksjonen fra Person.
---
.../bekk/bekkopen/person/Fodselsnummer.java | 42 +------------------
.../person/FodselsnummerCalculator.java | 28 -------------
.../java/no/bekk/bekkopen/person/Person.java | 9 ----
.../no/bekk/bekkopen/person/PersonTest.java | 9 +---
4 files changed, 3 insertions(+), 85 deletions(-)
diff --git a/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java b/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java
index 61ddc7a..d1a78d1 100644
--- a/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java
+++ b/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java
@@ -170,12 +170,9 @@ public String getIndividnummer() {
/**
* Returns the digit that decides the gender - the 9th in the Fodselsnummer.
- *
- * @deprecated For removal - Gender will stop working after 1.1.2032
- * Nytt fødselsnummer fra 2032
+ *
* @return The digit.
*/
- @Deprecated
public int getGenderDigit() {
return getAt(8);
}
@@ -198,30 +195,6 @@ public int getChecksumDigit2() {
return getAt(10);
}
- /**
- * Returns true if the Fodselsnummer represents a man.
- *
- * @deprecated For removal - Gender will stop working after 1.1.2032
- * Nytt fødselsnummer fra 2032
- * @return true or false.
- */
- @Deprecated
- public boolean isMale() {
- return getGenderDigit() % 2 != 0;
- }
-
- /**
- * Returns true if the Fodselsnummer represents a woman.
- *
- * @deprecated For removal - Gender will stop working after 1.1.2032
- * Nytt fødselsnummer fra 2032
- * @return true or false.
- */
- @Deprecated
- public boolean isFemale() {
- return !isMale();
- }
-
static String parseSyntheticNumber(String fodselsnummer) {
if (!isSynthetic(fodselsnummer)) {
return fodselsnummer;
@@ -291,19 +264,6 @@ private static int getThirdDigit(String fodselsnummer) {
return Integer.parseInt(fodselsnummer.substring(2, 3));
}
- /**
- * @deprecated For removal - Gender will stop working after 1.1.2032
- * Nytt fødselsnummer fra 2032
- */
- @Deprecated
- public KJONN getKjonn() {
- if (isFemale()) {
- return KJONN.KVINNE;
- } else {
- return KJONN.MANN;
- }
- }
-
@Override
public String toString() {
return super.getValue();
diff --git a/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java b/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java
index 1920e8e..0e1ccb9 100644
--- a/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java
+++ b/src/main/java/no/bekk/bekkopen/person/FodselsnummerCalculator.java
@@ -30,7 +30,6 @@
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.Iterator;
import java.util.List;
/**
@@ -42,22 +41,6 @@ private FodselsnummerCalculator() {
super();
}
- /**
- * Returns a List with valid Fodselsnummer instances for a given Date and gender.
- *
- * @deprecated For removal - Gender will stop working after 1.1.2032
- * Nytt fødselsnummer fra 2032
- *
- * @param date en dato
- * @param kjonn kjønn
- * @return liste med fødselsnummer
- */
- public static List getFodselsnummerForDateAndGender(LocalDate date, KJONN kjonn) {
- List result = getManyFodselsnummerForDate(date);
- splitByGender(kjonn, result);
- return result;
- }
-
/**
* Return one random valid fodselsnummer on a given date
* @param date en dato
@@ -174,15 +157,4 @@ private static List generateFodselsnummerForDate(String dateStrin
private static String getCentury(LocalDate date) {
return Integer.toString(date.getYear()).substring(0, 2);
}
-
- private static void splitByGender(KJONN kjonn, List result) {
- Iterator iter = result.iterator();
- while (iter.hasNext()) {
- Fodselsnummer f = iter.next();
- if (f.getKjonn() != kjonn) {
- iter.remove();
- }
- }
- }
-
}
diff --git a/src/main/java/no/bekk/bekkopen/person/Person.java b/src/main/java/no/bekk/bekkopen/person/Person.java
index 31960b4..ebde163 100644
--- a/src/main/java/no/bekk/bekkopen/person/Person.java
+++ b/src/main/java/no/bekk/bekkopen/person/Person.java
@@ -72,13 +72,4 @@ public LocalDate getFodselsdato() {
public String getPersonnummer() {
return this.fodselsnummer.getPersonnummer();
}
-
- public boolean erKvinne() {
- return fodselsnummer.isFemale();
- }
-
- public boolean erMann() {
- return fodselsnummer.isMale();
- }
-
}
diff --git a/src/test/java/no/bekk/bekkopen/person/PersonTest.java b/src/test/java/no/bekk/bekkopen/person/PersonTest.java
index 0308074..d6866a9 100644
--- a/src/test/java/no/bekk/bekkopen/person/PersonTest.java
+++ b/src/test/java/no/bekk/bekkopen/person/PersonTest.java
@@ -34,24 +34,19 @@
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class PersonTest {
@Test
- public void lagMann() {
+ public void lagPerson() {
LocalDate fodselsdato = LocalDate.of(1973, Month.DECEMBER, 10);
- List fodselsnumre = FodselsnummerCalculator.getFodselsnummerForDateAndGender(fodselsdato,
- KJONN.MANN);
+ List fodselsnumre = FodselsnummerCalculator.getManyFodselsnummerForDate(fodselsdato);
Fodselsnummer fodselsnummer = fodselsnumre.get(0);
Navn navn = NavnGenerator.genererMannsnavn();
Person person = new Person(navn, fodselsnummer);
- assertTrue(person.erMann());
- assertFalse(person.erKvinne());
-
String pFornavn = person.getFornavn();
assertTrue(pFornavn.matches(NavnGeneratorTest.NAVN_PATTERN),
pFornavn + " matcher ikke " + NavnGeneratorTest.NAVN_PATTERN);
From 29ab89627670f03ced4bd90cd7597705a7a97d8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eivind=20Bergst=C3=B8l?=
Date: Thu, 24 Sep 2026 15:52:29 +0200
Subject: [PATCH 6/7] Remove function regarding gender
---
src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java | 9 ---------
.../java/no/bekk/bekkopen/person/FodselsnummerTest.java | 5 -----
2 files changed, 14 deletions(-)
diff --git a/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java b/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java
index d1a78d1..37b83a5 100644
--- a/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java
+++ b/src/main/java/no/bekk/bekkopen/person/Fodselsnummer.java
@@ -168,15 +168,6 @@ public String getIndividnummer() {
return getValue().substring(6, 9);
}
- /**
- * Returns the digit that decides the gender - the 9th in the Fodselsnummer.
- *
- * @return The digit.
- */
- public int getGenderDigit() {
- return getAt(8);
- }
-
/**
* Returns the first checksum digit - the 10th in the Fodselsnummer.
*
diff --git a/src/test/java/no/bekk/bekkopen/person/FodselsnummerTest.java b/src/test/java/no/bekk/bekkopen/person/FodselsnummerTest.java
index 5dc39b4..f0eb72a 100644
--- a/src/test/java/no/bekk/bekkopen/person/FodselsnummerTest.java
+++ b/src/test/java/no/bekk/bekkopen/person/FodselsnummerTest.java
@@ -139,11 +139,6 @@ public void testGetIndividnummer() {
assertEquals("234", sut.getIndividnummer());
}
- @Test
- public void testGetGenderDigit() {
- assertEquals(4, sut.getGenderDigit());
- }
-
@Test
public void testGetChecksumDigits() {
assertEquals(7, sut.getChecksumDigit1());
From 68d5915555f31f0634319cdee714cac220a902dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Eivind=20Bergst=C3=B8l?=
Date: Thu, 24 Sep 2026 15:59:24 +0200
Subject: [PATCH 7/7] Fjern bruk av SimpleDateFormat til fordel for java.time
---
.../bekkopen/person/FodselsnummerValidator.java | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/src/main/java/no/bekk/bekkopen/person/FodselsnummerValidator.java b/src/main/java/no/bekk/bekkopen/person/FodselsnummerValidator.java
index 501b616..dbb50ac 100644
--- a/src/main/java/no/bekk/bekkopen/person/FodselsnummerValidator.java
+++ b/src/main/java/no/bekk/bekkopen/person/FodselsnummerValidator.java
@@ -31,9 +31,10 @@
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import java.net.URL;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeParseException;
+import java.time.format.ResolverStyle;
import static no.bekk.bekkopen.common.Checksums.ERROR_INVALID_CHECKSUM;
import static no.bekk.bekkopen.common.Checksums.calculateMod11CheckSum;
@@ -54,7 +55,7 @@ public class FodselsnummerValidator extends StringNumberValidator implements Con
private static final int LENGTH = 11;
- private static final String DATE_FORMAT = "ddMMyyyy";
+ private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("ddMMuuuu").withResolverStyle(ResolverStyle.STRICT);
private static final int[] K1_WEIGHTS = new int[] { 2, 5, 4, 9, 8, 1, 6, 7, 3 };
private static final int[] K2_WEIGHTS = new int[] { 2, 3, 4, 5, 6, 7, 2, 3, 4, 5 };
@@ -131,10 +132,8 @@ static void validateDate(String fodselsnummer) {
no.bekk.bekkopen.person.Fodselsnummer fnr = new no.bekk.bekkopen.person.Fodselsnummer(fodselsnummer);
try {
String dateString = fnr.getDateAndMonth() + fnr.getCentury() + fnr.get2DigitBirthYear();
- DateFormat df = new SimpleDateFormat(DATE_FORMAT);
- df.setLenient(false);
- df.parse(dateString);
- } catch (ParseException e) {
+ LocalDate.parse(dateString, DATE_FORMATTER);
+ } catch (DateTimeParseException e) {
throw new IllegalArgumentException(ERROR_INVALID_DATE + fodselsnummer);
}
}