TSK-867: Refactor DaysToWorkingDaysConverter

This commit is contained in:
Benjamin Eckstein 2019-11-12 14:36:12 +01:00 committed by holgerhagen
parent e80c81f698
commit 7b19390f36
3 changed files with 265 additions and 261 deletions

View File

@ -1,13 +1,19 @@
package pro.taskana.impl; package pro.taskana.impl;
import static java.time.temporal.ChronoUnit.DAYS;
import java.time.DayOfWeek; import java.time.DayOfWeek;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -27,12 +33,12 @@ public final class DaysToWorkingDaysConverter {
private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(TaskMonitorServiceImpl.class);
private static DaysToWorkingDaysConverter instance; private static DaysToWorkingDaysConverter instance;
private static ArrayList<Integer> positiveDaysToWorkingDays; private ArrayList<Integer> positiveDaysToWorkingDays;
private static ArrayList<Integer> negativeDaysToWorkingDays; private ArrayList<Integer> negativeDaysToWorkingDays;
private static Instant dateCreated; private Instant dateCreated;
private static LocalDate easterSunday; private LocalDate easterSunday;
private static boolean germanHolidaysEnabled; private static boolean germanHolidaysEnabled;
private static List<LocalDate> customHolidays; private static Set<LocalDate> customHolidays = new HashSet<>();
private DaysToWorkingDaysConverter(List<? extends TimeIntervalColumnHeader> columnHeaders, private DaysToWorkingDaysConverter(List<? extends TimeIntervalColumnHeader> columnHeaders,
Instant referenceDate) { Instant referenceDate) {
@ -46,11 +52,9 @@ public final class DaysToWorkingDaysConverter {
* Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and the current day. A * Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and the current day. A
* new table is only created if there are bigger limits or the date has changed. * new table is only created if there are bigger limits or the date has changed.
* *
* @param columnHeaders * @param columnHeaders a list of {@link TimeIntervalColumnHeader}s that determines the size of the table
* a list of {@link TimeIntervalColumnHeader}s that determines the size of the table
* @return an instance of the DaysToWorkingDaysConverter * @return an instance of the DaysToWorkingDaysConverter
* @throws InvalidArgumentException * @throws InvalidArgumentException thrown if columnHeaders is null
* thrown if columnHeaders is null
*/ */
public static DaysToWorkingDaysConverter initialize(List<? extends TimeIntervalColumnHeader> columnHeaders) public static DaysToWorkingDaysConverter initialize(List<? extends TimeIntervalColumnHeader> columnHeaders)
throws InvalidArgumentException { throws InvalidArgumentException {
@ -61,13 +65,10 @@ public final class DaysToWorkingDaysConverter {
* Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and a referenceDate. A * Initializes the DaysToWorkingDaysConverter for a list of {@link TimeIntervalColumnHeader}s and a referenceDate. A
* new table is only created if there are bigger limits or the date has changed. * new table is only created if there are bigger limits or the date has changed.
* *
* @param columnHeaders * @param columnHeaders a list of {@link TimeIntervalColumnHeader}s that determines the size of the table
* a list of {@link TimeIntervalColumnHeader}s that determines the size of the table * @param referenceDate a {@link Instant} that represents the current day of the table
* @param referenceDate
* a {@link Instant} that represents the current day of the table
* @return an instance of the DaysToWorkingDaysConverter * @return an instance of the DaysToWorkingDaysConverter
* @throws InvalidArgumentException * @throws InvalidArgumentException thrown if columnHeaders or referenceDate is null
* thrown if columnHeaders or referenceDate is null
*/ */
public static DaysToWorkingDaysConverter initialize(List<? extends TimeIntervalColumnHeader> columnHeaders, public static DaysToWorkingDaysConverter initialize(List<? extends TimeIntervalColumnHeader> columnHeaders,
Instant referenceDate) throws InvalidArgumentException { Instant referenceDate) throws InvalidArgumentException {
@ -81,40 +82,20 @@ public final class DaysToWorkingDaysConverter {
if (referenceDate == null) { if (referenceDate == null) {
throw new InvalidArgumentException("ReferenceDate can´t be used as NULL-Parameter"); throw new InvalidArgumentException("ReferenceDate can´t be used as NULL-Parameter");
} }
int largesLowerLimit = getLargestLowerLimit(columnHeaders); int largesLowerLimit = TimeIntervalColumnHeader.getLargestLowerLimit(columnHeaders);
int smallestUpperLimit = getSmallestUpperLimit(columnHeaders); int smallestUpperLimit = TimeIntervalColumnHeader.getSmallestUpperLimit(columnHeaders);
if (instance == null if (instance == null
|| !positiveDaysToWorkingDays.contains(largesLowerLimit) || !instance.positiveDaysToWorkingDays.contains(largesLowerLimit)
|| !negativeDaysToWorkingDays.contains(smallestUpperLimit) || !instance.negativeDaysToWorkingDays.contains(smallestUpperLimit)
|| !dateCreated.truncatedTo(ChronoUnit.DAYS).equals(referenceDate.truncatedTo(ChronoUnit.DAYS))) { || !instance.dateCreated.truncatedTo(DAYS).equals(referenceDate.truncatedTo(DAYS))) {
instance = new DaysToWorkingDaysConverter(columnHeaders, referenceDate); instance = new DaysToWorkingDaysConverter(columnHeaders, referenceDate);
LOGGER.debug("Create new converter for the values from {} until {} for the date: {}.", largesLowerLimit, LOGGER.debug("Create new converter for the values from {} until {} for the date: {}.", largesLowerLimit,
smallestUpperLimit, dateCreated); smallestUpperLimit, instance.dateCreated);
} }
return instance; return instance;
} }
private static int getSmallestUpperLimit(List<? extends TimeIntervalColumnHeader> columnHeaders) {
int smallestUpperLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() < smallestUpperLimit) {
smallestUpperLimit = columnHeader.getUpperAgeLimit();
}
}
return smallestUpperLimit;
}
private static int getLargestLowerLimit(List<? extends TimeIntervalColumnHeader> columnHeaders) {
int greatestLowerLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() > greatestLowerLimit) {
greatestLowerLimit = columnHeader.getLowerAgeLimit();
}
}
return greatestLowerLimit;
}
public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) { public static void setGermanPublicHolidaysEnabled(boolean germanPublicHolidaysEnabled) {
germanHolidaysEnabled = germanPublicHolidaysEnabled; germanHolidaysEnabled = germanPublicHolidaysEnabled;
} }
@ -124,8 +105,7 @@ public final class DaysToWorkingDaysConverter {
* created by initialization. If the age in days is beyond the limits of the table, the integer will be returned * created by initialization. If the age in days is beyond the limits of the table, the integer will be returned
* unchanged. * unchanged.
* *
* @param ageInDays * @param ageInDays represents the age in days
* represents the age in days
* @return the age in working days * @return the age in working days
*/ */
public int convertDaysToWorkingDays(int ageInDays) { public int convertDaysToWorkingDays(int ageInDays) {
@ -149,8 +129,7 @@ public final class DaysToWorkingDaysConverter {
* value is a list of all days that match to the input parameter. If the age in working days is beyond the limits of * value is a list of all days that match to the input parameter. If the age in working days is beyond the limits of
* the table, the integer will be returned unchanged. * the table, the integer will be returned unchanged.
* *
* @param ageInWorkingDays * @param ageInWorkingDays represents the age in working days
* represents the age in working days
* @return a list of age in days * @return a list of age in days
*/ */
public ArrayList<Integer> convertWorkingDaysToDays(int ageInWorkingDays) { public ArrayList<Integer> convertWorkingDaysToDays(int ageInWorkingDays) {
@ -201,97 +180,85 @@ public final class DaysToWorkingDaysConverter {
int days = 0; int days = 0;
int workingDays = 0; int workingDays = 0;
while (workingDays < numberOfDays) { while (workingDays < numberOfDays) {
if (isWorkingDay(days, startTime)) { workingDays += isWorkingDay(++days, startTime) ? 1 : 0;
workingDays++;
}
days++;
while (!isWorkingDay(days, startTime)) {
days++;
}
} }
return days; return days;
} }
private ArrayList<Integer> generateNegativeDaysToWorkingDays( private ArrayList<Integer> generateNegativeDaysToWorkingDays(
List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) { List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) {
int minUpperLimit = getSmallestUpperLimit(columnHeaders); int minUpperLimit = TimeIntervalColumnHeader.getSmallestUpperLimit(columnHeaders);
ArrayList<Integer> daysToWorkingDays = new ArrayList<>(); ArrayList<Integer> daysToWorkingDays = new ArrayList<>();
daysToWorkingDays.add(0); daysToWorkingDays.add(0);
int day = -1; int day = -1;
int workingDay = 0; int workingDay = 0;
while (workingDay > minUpperLimit) { while (workingDay > minUpperLimit) {
if (isWorkingDay(day, referenceDate)) { workingDay -= (isWorkingDay(day--, referenceDate)) ? 1 : 0;
workingDay--;
}
daysToWorkingDays.add(workingDay); daysToWorkingDays.add(workingDay);
day--;
} }
return daysToWorkingDays; return daysToWorkingDays;
} }
private ArrayList<Integer> generatePositiveDaysToWorkingDays( private ArrayList<Integer> generatePositiveDaysToWorkingDays(
List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) { List<? extends TimeIntervalColumnHeader> columnHeaders, Instant referenceDate) {
int maxLowerLimit = getLargestLowerLimit(columnHeaders); int maxLowerLimit = TimeIntervalColumnHeader.getLargestLowerLimit(columnHeaders);
ArrayList<Integer> daysToWorkingDays = new ArrayList<>(); ArrayList<Integer> daysToWorkingDays = new ArrayList<>();
daysToWorkingDays.add(0); daysToWorkingDays.add(0);
int day = 1; int day = 1;
int workingDay = 0; int workingDay = 0;
while (workingDay < maxLowerLimit) { while (workingDay < maxLowerLimit) {
if (isWorkingDay(day, referenceDate)) { workingDay += (isWorkingDay(day++, referenceDate)) ? 1 : 0;
workingDay++;
}
daysToWorkingDays.add(workingDay); daysToWorkingDays.add(workingDay);
day++;
} }
return daysToWorkingDays; return daysToWorkingDays;
} }
private boolean isWorkingDay(int day, Instant referenceDate) { private boolean isWorkingDay(int day, Instant referenceDate) {
LocalDateTime dateTime = LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day); LocalDateTime dateToCheck = LocalDateTime.ofInstant(referenceDate, ZoneId.systemDefault()).plusDays(day);
if (dateTime.getDayOfWeek().equals(DayOfWeek.SATURDAY)
|| dateTime.getDayOfWeek().equals(DayOfWeek.SUNDAY) return !isWeekend(dateToCheck)
|| isHoliday(dateTime.toLocalDate())) { && !isHoliday(dateToCheck.toLocalDate());
return false; }
}
return true; private boolean isWeekend(LocalDateTime dateToCheck) {
return dateToCheck.getDayOfWeek().equals(DayOfWeek.SATURDAY)
|| dateToCheck.getDayOfWeek().equals(DayOfWeek.SUNDAY);
} }
private boolean isHoliday(LocalDate date) { private boolean isHoliday(LocalDate date) {
if (germanHolidaysEnabled) { if (germanHolidaysEnabled && isGermanHoliday(date)) {
// Fix and movable holidays that are valid throughout Germany: New years day, Labour Day, Day of German return true;
// Unity, Christmas, Good Friday, Easter Monday, Ascension Day, Whit Monday.
if (date.getDayOfMonth() == 1 && date.getMonthValue() == 1
|| date.getDayOfMonth() == 1 && date.getMonthValue() == 5
|| date.getDayOfMonth() == 3 && date.getMonthValue() == 10
|| date.getDayOfMonth() == 25 && date.getMonthValue() == 12
|| date.getDayOfMonth() == 26 && date.getMonthValue() == 12
|| easterSunday.minusDays(2).equals(date)
|| easterSunday.plusDays(1).equals(date)
|| easterSunday.plusDays(39).equals(date)
|| easterSunday.plusDays(50).equals(date)) {
return true;
}
} }
if (customHolidays != null) { // Custom holidays that can be configured in the TaskanaEngineConfiguration
// Custom holidays that can be configured in the TaskanaEngineConfiguration return customHolidays.contains(date);
for (LocalDate customHoliday : customHolidays) { }
if (date.equals(customHoliday)) {
return true; private boolean isGermanHoliday(LocalDate date) {
} // Fix and movable holidays that are valid throughout Germany: New years day, Labour Day, Day of German
} // Unity, Christmas,
if (Stream.of(GermanFixHolidays.values()).anyMatch(day -> day.matches(date))) {
return true;
} }
return false;
// Easter holidays Good Friday, Easter Monday, Ascension Day, Whit Monday.
long diffFromEasterSunday = DAYS.between(easterSunday, date);
long goodFriday = -2;
long easterMonday = 1;
long ascensionDay = 39;
long whitMonday = 50;
return LongStream.of(goodFriday, easterMonday, ascensionDay, whitMonday)
.anyMatch(diff -> diff == diffFromEasterSunday);
} }
/** /**
* Computes the date of Easter Sunday for a given year. * Computes the date of Easter Sunday for a given year.
* *
* @param year * @param year for which the date of Easter Sunday should be calculated
* for which the date of Easter Sunday should be calculated
* @return the date of Easter Sunday for the given year * @return the date of Easter Sunday for the given year
*/ */
public LocalDate getEasterSunday(int year) { static LocalDate getEasterSunday(int year) {
// Formula to compute Easter Sunday by Gauss. // Formula to compute Easter Sunday by Gauss.
int a = year % 19; int a = year % 19;
int b = year % 4; int b = year % 4;
@ -314,16 +281,8 @@ public final class DaysToWorkingDaysConverter {
return LocalDate.of(year, 3, 22).plusDays(d + e); return LocalDate.of(year, 3, 22).plusDays(d + e);
} }
public List<LocalDate> getCustomHolidays() {
return customHolidays;
}
public static void setCustomHolidays(List<LocalDate> holidays) { public static void setCustomHolidays(List<LocalDate> holidays) {
customHolidays = holidays; customHolidays = new HashSet<>(holidays == null ? Collections.emptyList() : holidays);
}
public boolean isGermanPublicHolidayEnabled() {
return germanHolidaysEnabled;
} }
@Override @Override
@ -333,6 +292,29 @@ public final class DaysToWorkingDaysConverter {
+ ", negativeDaysToWorkingDays= " + negativeDaysToWorkingDays + ", negativeDaysToWorkingDays= " + negativeDaysToWorkingDays
+ ", dateCreated= " + dateCreated + ", easterSunday= " + easterSunday + ", dateCreated= " + dateCreated + ", easterSunday= " + easterSunday
+ ", germanHolidaysEnabled= " + germanHolidaysEnabled + ", germanHolidaysEnabled= " + germanHolidaysEnabled
+ ", customHolidays= " + LoggerUtils.listToString(customHolidays) + "]"; + ", customHolidays= " + LoggerUtils.setToString(customHolidays) + "]";
}
/**
* Enumeration of German holidays.
*/
private enum GermanFixHolidays {
NEWYEAR(1, 1),
LABOURDAY(5, 1),
GERMANUNITY(10, 3),
CHRISTMAS1(12, 25),
CHRISTMAS2(12, 26);
private int month;
private int day;
GermanFixHolidays(int month, int day) {
this.month = month;
this.day = day;
}
public boolean matches(LocalDate date) {
return date.getDayOfMonth() == day && date.getMonthValue() == month;
}
} }
} }

View File

@ -2,6 +2,7 @@ package pro.taskana.impl.report.header;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import pro.taskana.impl.report.item.AgeQueryItem; import pro.taskana.impl.report.item.AgeQueryItem;
@ -30,6 +31,24 @@ public class TimeIntervalColumnHeader implements ColumnHeader<AgeQueryItem> {
this.upperAgeLimit = upperAgeLimit; this.upperAgeLimit = upperAgeLimit;
} }
public static int getSmallestUpperLimit(List<? extends TimeIntervalColumnHeader> columnHeaders) {
return columnHeaders.stream()
.mapToInt(TimeIntervalColumnHeader::getUpperAgeLimit)
.filter(i -> i < 0)
.min()
.orElse(0);
}
public static int getLargestLowerLimit(List<? extends TimeIntervalColumnHeader> columnHeaders) {
int greatestLowerLimit = 0;
for (TimeIntervalColumnHeader columnHeader : columnHeaders) {
if (columnHeader.getUpperAgeLimit() > greatestLowerLimit) {
greatestLowerLimit = columnHeader.getLowerAgeLimit();
}
}
return greatestLowerLimit;
}
public int getLowerAgeLimit() { public int getLowerAgeLimit() {
return lowerAgeLimit; return lowerAgeLimit;
} }

View File

@ -1,18 +1,18 @@
package pro.taskana.impl; package pro.taskana.impl;
import static java.util.Collections.singletonList;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail; import static pro.taskana.impl.DaysToWorkingDaysConverter.getEasterSunday;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import org.junit.BeforeClass; import org.junit.jupiter.api.BeforeAll;
import org.junit.Test; import org.junit.jupiter.api.Test;
import pro.taskana.exceptions.InvalidArgumentException; import pro.taskana.exceptions.InvalidArgumentException;
import pro.taskana.impl.report.header.TimeIntervalColumnHeader; import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
@ -20,10 +20,10 @@ import pro.taskana.impl.report.header.TimeIntervalColumnHeader;
/** /**
* Test for the DaysToWorkingDaysConverter. * Test for the DaysToWorkingDaysConverter.
*/ */
public class DaysToWorkingDaysConverterTest { class DaysToWorkingDaysConverterTest {
@BeforeClass @BeforeAll
public static void setup() { static void setup() {
DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true); DaysToWorkingDaysConverter.setGermanPublicHolidaysEnabled(true);
LocalDate dayOfReformation = LocalDate.of(2018, 10, 31); LocalDate dayOfReformation = LocalDate.of(2018, 10, 31);
LocalDate allSaintsDays = LocalDate.of(2018, 11, 1); LocalDate allSaintsDays = LocalDate.of(2018, 11, 1);
@ -31,7 +31,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testInitializeForDifferentReportLineItemDefinitions() throws InvalidArgumentException { void testInitializeForDifferentReportLineItemDefinitions() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter
.initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z")); .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-03T00:00:00.000Z"));
DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter
@ -44,63 +44,68 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testConvertWorkingDaysToDaysForTasks() { void testConvertWorkingDaysToDaysForTasks() throws InvalidArgumentException {
List<TimeIntervalColumnHeader> reportItems = Collections.singletonList(new TimeIntervalColumnHeader(0)); List<TimeIntervalColumnHeader> reportItems = singletonList(new TimeIntervalColumnHeader(0));
try { Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z"); DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(reportItems, thursday0201);
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(reportItems, thursday0201);
long days = converter.convertWorkingDaysToDays(thursday0201, 0); // = thursday
assertEquals(0, days);
days = converter.convertWorkingDaysToDays(thursday0201, 1); // fri
assertEquals(1, days);
days = converter.convertWorkingDaysToDays(thursday0201, 2); // mon
assertEquals(4, days);
days = converter.convertWorkingDaysToDays(thursday0201, 3); // tues
assertEquals(5, days);
days = converter.convertWorkingDaysToDays(thursday0201, 4); // we
assertEquals(6, days);
days = converter.convertWorkingDaysToDays(thursday0201, 5); // thurs
assertEquals(7, days);
days = converter.convertWorkingDaysToDays(thursday0201, 6); // fri
assertEquals(8, days);
days = converter.convertWorkingDaysToDays(thursday0201, 7); // mon
assertEquals(11, days);
days = converter.convertWorkingDaysToDays(thursday0201, 8); // tue
assertEquals(12, days);
days = converter.convertWorkingDaysToDays(thursday0201, 9); // we
assertEquals(13, days);
days = converter.convertWorkingDaysToDays(thursday0201, 10); // thu
assertEquals(14, days);
days = converter.convertWorkingDaysToDays(thursday0201, 11); // fri
assertEquals(15, days);
Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z");
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 0);
assertEquals(0, days);
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 1); // Karfreitag
assertEquals(5, days); // osterdienstag
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 2); // Karfreitag
assertEquals(6, days); // ostermittwoch
Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z");
days = converter.convertWorkingDaysToDays(freitag0427, 0);
assertEquals(0, days);
days = converter.convertWorkingDaysToDays(freitag0427, 1);
assertEquals(3, days); // 30.4.
days = converter.convertWorkingDaysToDays(freitag0427, 2);
assertEquals(5, days); // 2.5.
} catch (InvalidArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
fail("");
}
long days = converter.convertWorkingDaysToDays(thursday0201, 0); // = thursday
assertEquals(0, days);
days = converter.convertWorkingDaysToDays(thursday0201, 1); // fri
assertEquals(1, days);
days = converter.convertWorkingDaysToDays(thursday0201, 2); // mon
assertEquals(4, days);
days = converter.convertWorkingDaysToDays(thursday0201, 3); // tues
assertEquals(5, days);
days = converter.convertWorkingDaysToDays(thursday0201, 4); // we
assertEquals(6, days);
days = converter.convertWorkingDaysToDays(thursday0201, 5); // thurs
assertEquals(7, days);
days = converter.convertWorkingDaysToDays(thursday0201, 6); // fri
assertEquals(8, days);
days = converter.convertWorkingDaysToDays(thursday0201, 7); // mon
assertEquals(11, days);
days = converter.convertWorkingDaysToDays(thursday0201, 8); // tue
assertEquals(12, days);
days = converter.convertWorkingDaysToDays(thursday0201, 9); // we
assertEquals(13, days);
days = converter.convertWorkingDaysToDays(thursday0201, 10); // thu
assertEquals(14, days);
days = converter.convertWorkingDaysToDays(thursday0201, 11); // fri
assertEquals(15, days);
} }
@Test @Test
public void testInitializeForDifferentDates() throws InvalidArgumentException { void testConvertWorkingDaysToDaysForKarFreitag() throws InvalidArgumentException {
List<TimeIntervalColumnHeader> reportItems = singletonList(new TimeIntervalColumnHeader(0));
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(reportItems, thursday0201);
Instant gruenDonnerstag2018 = Instant.parse("2018-03-29T01:00:00.000Z");
long days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 0);
assertEquals(0, days);
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 1); // Karfreitag
assertEquals(5, days); // osterdienstag
days = converter.convertWorkingDaysToDays(gruenDonnerstag2018, 2); // Karfreitag
assertEquals(6, days); // ostermittwoch
}
@Test
void testConvertWorkingDaysToDaysForHolidays() throws InvalidArgumentException {
List<TimeIntervalColumnHeader> reportItems = singletonList(new TimeIntervalColumnHeader(0));
Instant thursday0201 = Instant.parse("2018-02-01T07:00:00.000Z");
DaysToWorkingDaysConverter converter = DaysToWorkingDaysConverter.initialize(reportItems, thursday0201);
Instant freitag0427 = Instant.parse("2018-04-27T19:00:00.000Z");
long days = converter.convertWorkingDaysToDays(freitag0427, 0);
assertEquals(0, days);
days = converter.convertWorkingDaysToDays(freitag0427, 1);
assertEquals(3, days); // 30.4.
days = converter.convertWorkingDaysToDays(freitag0427, 2);
assertEquals(5, days); // 2.5.
}
@Test
void testInitializeForDifferentDates() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance1 = DaysToWorkingDaysConverter
.initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-04T00:00:00.000Z")); .initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-04T00:00:00.000Z"));
DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance2 = DaysToWorkingDaysConverter
@ -110,7 +115,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testConvertDaysToWorkingDays() throws InvalidArgumentException { void testConvertDaysToWorkingDays() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-06T00:00:00.000Z"));
@ -134,106 +139,106 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testConvertWorkingDaysToDays() throws InvalidArgumentException { void testConvertWorkingDaysToDays() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z"));
assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); assertEquals(singletonList(-13), instance.convertWorkingDaysToDays(-13));
assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); assertEquals(singletonList(-12), instance.convertWorkingDaysToDays(-12));
assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-8)); assertEquals(singletonList(-12), instance.convertWorkingDaysToDays(-8));
assertEquals(Arrays.asList(-11), instance.convertWorkingDaysToDays(-7)); assertEquals(singletonList(-11), instance.convertWorkingDaysToDays(-7));
assertEquals(Arrays.asList(-8, -9, -10), instance.convertWorkingDaysToDays(-6)); assertEquals(Arrays.asList(-8, -9, -10), instance.convertWorkingDaysToDays(-6));
assertEquals(Arrays.asList(-7), instance.convertWorkingDaysToDays(-5)); assertEquals(singletonList(-7), instance.convertWorkingDaysToDays(-5));
assertEquals(Arrays.asList(-6), instance.convertWorkingDaysToDays(-4)); assertEquals(singletonList(-6), instance.convertWorkingDaysToDays(-4));
assertEquals(Arrays.asList(-5), instance.convertWorkingDaysToDays(-3)); assertEquals(singletonList(-5), instance.convertWorkingDaysToDays(-3));
assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-2)); assertEquals(singletonList(-4), instance.convertWorkingDaysToDays(-2));
assertEquals(Arrays.asList(-1, -2, -3), instance.convertWorkingDaysToDays(-1)); assertEquals(Arrays.asList(-1, -2, -3), instance.convertWorkingDaysToDays(-1));
assertEquals(Arrays.asList(0), instance.convertWorkingDaysToDays(0)); assertEquals(singletonList(0), instance.convertWorkingDaysToDays(0));
assertEquals(Arrays.asList(1), instance.convertWorkingDaysToDays(1)); assertEquals(singletonList(1), instance.convertWorkingDaysToDays(1));
assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(2)); assertEquals(singletonList(2), instance.convertWorkingDaysToDays(2));
assertEquals(Arrays.asList(3, 4, 5), instance.convertWorkingDaysToDays(3)); assertEquals(Arrays.asList(3, 4, 5), instance.convertWorkingDaysToDays(3));
assertEquals(Arrays.asList(6), instance.convertWorkingDaysToDays(4)); assertEquals(singletonList(6), instance.convertWorkingDaysToDays(4));
assertEquals(Arrays.asList(7), instance.convertWorkingDaysToDays(5)); assertEquals(singletonList(7), instance.convertWorkingDaysToDays(5));
assertEquals(Arrays.asList(8), instance.convertWorkingDaysToDays(6)); assertEquals(singletonList(8), instance.convertWorkingDaysToDays(6));
assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(7)); assertEquals(singletonList(9), instance.convertWorkingDaysToDays(7));
assertEquals(Arrays.asList(10, 11, 12), instance.convertWorkingDaysToDays(8)); assertEquals(Arrays.asList(10, 11, 12), instance.convertWorkingDaysToDays(8));
assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(9)); assertEquals(singletonList(13), instance.convertWorkingDaysToDays(9));
assertEquals(Arrays.asList(14), instance.convertWorkingDaysToDays(10)); assertEquals(singletonList(14), instance.convertWorkingDaysToDays(10));
assertEquals(Arrays.asList(15), instance.convertWorkingDaysToDays(11)); assertEquals(singletonList(15), instance.convertWorkingDaysToDays(11));
assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); assertEquals(singletonList(12), instance.convertWorkingDaysToDays(12));
assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); assertEquals(singletonList(13), instance.convertWorkingDaysToDays(13));
} }
@Test @Test
public void testConvertWorkingDaysToDaysAtWeekend() throws InvalidArgumentException { void testConvertWorkingDaysToDaysAtWeekend() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-10T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-10T00:00:00.000Z"));
assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); assertEquals(singletonList(-13), instance.convertWorkingDaysToDays(-13));
assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); assertEquals(singletonList(-12), instance.convertWorkingDaysToDays(-12));
assertEquals(Arrays.asList(-10), instance.convertWorkingDaysToDays(-8)); assertEquals(singletonList(-10), instance.convertWorkingDaysToDays(-8));
assertEquals(Arrays.asList(-9), instance.convertWorkingDaysToDays(-7)); assertEquals(singletonList(-9), instance.convertWorkingDaysToDays(-7));
assertEquals(Arrays.asList(-8), instance.convertWorkingDaysToDays(-6)); assertEquals(singletonList(-8), instance.convertWorkingDaysToDays(-6));
assertEquals(Arrays.asList(-5, -6, -7), instance.convertWorkingDaysToDays(-5)); assertEquals(Arrays.asList(-5, -6, -7), instance.convertWorkingDaysToDays(-5));
assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-4)); assertEquals(singletonList(-4), instance.convertWorkingDaysToDays(-4));
assertEquals(Arrays.asList(-3), instance.convertWorkingDaysToDays(-3)); assertEquals(singletonList(-3), instance.convertWorkingDaysToDays(-3));
assertEquals(Arrays.asList(-2), instance.convertWorkingDaysToDays(-2)); assertEquals(singletonList(-2), instance.convertWorkingDaysToDays(-2));
assertEquals(Arrays.asList(-1), instance.convertWorkingDaysToDays(-1)); assertEquals(singletonList(-1), instance.convertWorkingDaysToDays(-1));
assertEquals(Arrays.asList(0, 1), instance.convertWorkingDaysToDays(0)); assertEquals(Arrays.asList(0, 1), instance.convertWorkingDaysToDays(0));
assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(1)); assertEquals(singletonList(2), instance.convertWorkingDaysToDays(1));
assertEquals(Arrays.asList(3), instance.convertWorkingDaysToDays(2)); assertEquals(singletonList(3), instance.convertWorkingDaysToDays(2));
assertEquals(Arrays.asList(4), instance.convertWorkingDaysToDays(3)); assertEquals(singletonList(4), instance.convertWorkingDaysToDays(3));
assertEquals(Arrays.asList(5), instance.convertWorkingDaysToDays(4)); assertEquals(singletonList(5), instance.convertWorkingDaysToDays(4));
assertEquals(Arrays.asList(6, 7, 8), instance.convertWorkingDaysToDays(5)); assertEquals(Arrays.asList(6, 7, 8), instance.convertWorkingDaysToDays(5));
assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(6)); assertEquals(singletonList(9), instance.convertWorkingDaysToDays(6));
assertEquals(Arrays.asList(10), instance.convertWorkingDaysToDays(7)); assertEquals(singletonList(10), instance.convertWorkingDaysToDays(7));
assertEquals(Arrays.asList(11), instance.convertWorkingDaysToDays(8)); assertEquals(singletonList(11), instance.convertWorkingDaysToDays(8));
assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(9)); assertEquals(singletonList(12), instance.convertWorkingDaysToDays(9));
assertEquals(Arrays.asList(13, 14, 15), instance.convertWorkingDaysToDays(10)); assertEquals(Arrays.asList(13, 14, 15), instance.convertWorkingDaysToDays(10));
assertEquals(Arrays.asList(16), instance.convertWorkingDaysToDays(11)); assertEquals(singletonList(16), instance.convertWorkingDaysToDays(11));
assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); assertEquals(singletonList(12), instance.convertWorkingDaysToDays(12));
assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); assertEquals(singletonList(13), instance.convertWorkingDaysToDays(13));
} }
@Test @Test
public void testConvertWorkingDaysToDaysOnEasterSunday() throws InvalidArgumentException { void testConvertWorkingDaysToDaysOnEasterSunday() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-01T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-01T00:00:00.000Z"));
assertEquals(Arrays.asList(-13), instance.convertWorkingDaysToDays(-13)); assertEquals(singletonList(-13), instance.convertWorkingDaysToDays(-13));
assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-12)); assertEquals(singletonList(-12), instance.convertWorkingDaysToDays(-12));
assertEquals(Arrays.asList(-12), instance.convertWorkingDaysToDays(-8)); assertEquals(singletonList(-12), instance.convertWorkingDaysToDays(-8));
assertEquals(Arrays.asList(-11), instance.convertWorkingDaysToDays(-7)); assertEquals(singletonList(-11), instance.convertWorkingDaysToDays(-7));
assertEquals(Arrays.asList(-10), instance.convertWorkingDaysToDays(-6)); assertEquals(singletonList(-10), instance.convertWorkingDaysToDays(-6));
assertEquals(Arrays.asList(-9), instance.convertWorkingDaysToDays(-5)); assertEquals(singletonList(-9), instance.convertWorkingDaysToDays(-5));
assertEquals(Arrays.asList(-6, -7, -8), instance.convertWorkingDaysToDays(-4)); assertEquals(Arrays.asList(-6, -7, -8), instance.convertWorkingDaysToDays(-4));
assertEquals(Arrays.asList(-5), instance.convertWorkingDaysToDays(-3)); assertEquals(singletonList(-5), instance.convertWorkingDaysToDays(-3));
assertEquals(Arrays.asList(-4), instance.convertWorkingDaysToDays(-2)); assertEquals(singletonList(-4), instance.convertWorkingDaysToDays(-2));
assertEquals(Arrays.asList(-3), instance.convertWorkingDaysToDays(-1)); assertEquals(singletonList(-3), instance.convertWorkingDaysToDays(-1));
assertEquals(Arrays.asList(0, 1, -1, -2), instance.convertWorkingDaysToDays(0)); assertEquals(Arrays.asList(0, 1, -1, -2), instance.convertWorkingDaysToDays(0));
assertEquals(Arrays.asList(2), instance.convertWorkingDaysToDays(1)); assertEquals(singletonList(2), instance.convertWorkingDaysToDays(1));
assertEquals(Arrays.asList(3), instance.convertWorkingDaysToDays(2)); assertEquals(singletonList(3), instance.convertWorkingDaysToDays(2));
assertEquals(Arrays.asList(4), instance.convertWorkingDaysToDays(3)); assertEquals(singletonList(4), instance.convertWorkingDaysToDays(3));
assertEquals(Arrays.asList(5, 6, 7), instance.convertWorkingDaysToDays(4)); assertEquals(Arrays.asList(5, 6, 7), instance.convertWorkingDaysToDays(4));
assertEquals(Arrays.asList(8), instance.convertWorkingDaysToDays(5)); assertEquals(singletonList(8), instance.convertWorkingDaysToDays(5));
assertEquals(Arrays.asList(9), instance.convertWorkingDaysToDays(6)); assertEquals(singletonList(9), instance.convertWorkingDaysToDays(6));
assertEquals(Arrays.asList(10), instance.convertWorkingDaysToDays(7)); assertEquals(singletonList(10), instance.convertWorkingDaysToDays(7));
assertEquals(Arrays.asList(11), instance.convertWorkingDaysToDays(8)); assertEquals(singletonList(11), instance.convertWorkingDaysToDays(8));
assertEquals(Arrays.asList(12, 13, 14), instance.convertWorkingDaysToDays(9)); assertEquals(Arrays.asList(12, 13, 14), instance.convertWorkingDaysToDays(9));
assertEquals(Arrays.asList(15), instance.convertWorkingDaysToDays(10)); assertEquals(singletonList(15), instance.convertWorkingDaysToDays(10));
assertEquals(Arrays.asList(16), instance.convertWorkingDaysToDays(11)); assertEquals(singletonList(16), instance.convertWorkingDaysToDays(11));
assertEquals(Arrays.asList(12), instance.convertWorkingDaysToDays(12)); assertEquals(singletonList(12), instance.convertWorkingDaysToDays(12));
assertEquals(Arrays.asList(13), instance.convertWorkingDaysToDays(13)); assertEquals(singletonList(13), instance.convertWorkingDaysToDays(13));
} }
@Test @Test
public void testEasterHolidays() throws InvalidArgumentException { void testEasterHolidays() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-28T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-03-28T00:00:00.000Z"));
@ -247,7 +252,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testWhitsunHolidays() throws InvalidArgumentException { void testWhitsunHolidays() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-16T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-16T00:00:00.000Z"));
@ -261,7 +266,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testLabourDayHoliday() throws InvalidArgumentException { void testLabourDayHoliday() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-26T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-04-26T00:00:00.000Z"));
@ -276,7 +281,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testAscensionDayHoliday() throws InvalidArgumentException { void testAscensionDayHoliday() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-07T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-05-07T00:00:00.000Z"));
@ -291,7 +296,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testDayOfGermanUnityHoliday() throws InvalidArgumentException { void testDayOfGermanUnityHoliday() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-01T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-01T00:00:00.000Z"));
@ -306,7 +311,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testChristmasAndNewYearHolidays() throws InvalidArgumentException { void testChristmasAndNewYearHolidays() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-12-20T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-12-20T00:00:00.000Z"));
@ -328,7 +333,7 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testCustomHolidaysWithDayOfReformationAndAllSaintsDay() throws InvalidArgumentException { void testCustomHolidaysWithDayOfReformationAndAllSaintsDay() throws InvalidArgumentException {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-26T00:00:00.000Z")); .initialize(getLargeListOfColumnHeaders(), Instant.parse("2018-10-26T00:00:00.000Z"));
@ -344,31 +349,29 @@ public class DaysToWorkingDaysConverterTest {
} }
@Test @Test
public void testGetEasterSunday() throws InvalidArgumentException { void testGetEasterSunday() {
DaysToWorkingDaysConverter instance = DaysToWorkingDaysConverter
.initialize(getShortListOfColumnHeaders(), Instant.parse("2018-02-27T00:00:00.000Z"));
assertEquals(LocalDate.of(2018, 4, 1), instance.getEasterSunday(2018)); assertEquals(LocalDate.of(2018, 4, 1), getEasterSunday(2018));
assertEquals(LocalDate.of(2019, 4, 21), instance.getEasterSunday(2019)); assertEquals(LocalDate.of(2019, 4, 21), getEasterSunday(2019));
assertEquals(LocalDate.of(2020, 4, 12), instance.getEasterSunday(2020)); assertEquals(LocalDate.of(2020, 4, 12), getEasterSunday(2020));
assertEquals(LocalDate.of(2021, 4, 4), instance.getEasterSunday(2021)); assertEquals(LocalDate.of(2021, 4, 4), getEasterSunday(2021));
assertEquals(LocalDate.of(2022, 4, 17), instance.getEasterSunday(2022)); assertEquals(LocalDate.of(2022, 4, 17), getEasterSunday(2022));
assertEquals(LocalDate.of(2023, 4, 9), instance.getEasterSunday(2023)); assertEquals(LocalDate.of(2023, 4, 9), getEasterSunday(2023));
assertEquals(LocalDate.of(2024, 3, 31), instance.getEasterSunday(2024)); assertEquals(LocalDate.of(2024, 3, 31), getEasterSunday(2024));
assertEquals(LocalDate.of(2025, 4, 20), instance.getEasterSunday(2025)); assertEquals(LocalDate.of(2025, 4, 20), getEasterSunday(2025));
assertEquals(LocalDate.of(2026, 4, 5), instance.getEasterSunday(2026)); assertEquals(LocalDate.of(2026, 4, 5), getEasterSunday(2026));
assertEquals(LocalDate.of(2027, 3, 28), instance.getEasterSunday(2027)); assertEquals(LocalDate.of(2027, 3, 28), getEasterSunday(2027));
assertEquals(LocalDate.of(2028, 4, 16), instance.getEasterSunday(2028)); assertEquals(LocalDate.of(2028, 4, 16), getEasterSunday(2028));
assertEquals(LocalDate.of(2029, 4, 1), instance.getEasterSunday(2029)); assertEquals(LocalDate.of(2029, 4, 1), getEasterSunday(2029));
assertEquals(LocalDate.of(2030, 4, 21), instance.getEasterSunday(2030)); assertEquals(LocalDate.of(2030, 4, 21), getEasterSunday(2030));
assertEquals(LocalDate.of(2031, 4, 13), instance.getEasterSunday(2031)); assertEquals(LocalDate.of(2031, 4, 13), getEasterSunday(2031));
assertEquals(LocalDate.of(2032, 3, 28), instance.getEasterSunday(2032)); assertEquals(LocalDate.of(2032, 3, 28), getEasterSunday(2032));
assertEquals(LocalDate.of(2033, 4, 17), instance.getEasterSunday(2033)); assertEquals(LocalDate.of(2033, 4, 17), getEasterSunday(2033));
assertEquals(LocalDate.of(2034, 4, 9), instance.getEasterSunday(2034)); assertEquals(LocalDate.of(2034, 4, 9), getEasterSunday(2034));
assertEquals(LocalDate.of(2035, 3, 25), instance.getEasterSunday(2035)); assertEquals(LocalDate.of(2035, 3, 25), getEasterSunday(2035));
assertEquals(LocalDate.of(2040, 4, 1), instance.getEasterSunday(2040)); assertEquals(LocalDate.of(2040, 4, 1), getEasterSunday(2040));
assertEquals(LocalDate.of(2050, 4, 10), instance.getEasterSunday(2050)); assertEquals(LocalDate.of(2050, 4, 10), getEasterSunday(2050));
assertEquals(LocalDate.of(2100, 3, 28), instance.getEasterSunday(2100)); assertEquals(LocalDate.of(2100, 3, 28), getEasterSunday(2100));
} }