Skip to content

Commit

Permalink
Provide original holiday date and observed holiday date
Browse files Browse the repository at this point in the history
  • Loading branch information
derTobsch committed Jan 1, 2025
1 parent 08832f4 commit 71327fa
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

import java.time.LocalDate;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;

/**
* Represents the holiday and contains the actual date and an localized
Expand All @@ -17,7 +19,11 @@ public final class Holiday implements Comparable<Holiday> {
/**
* The date the holiday occurs.
*/
private final LocalDate date;
private final LocalDate actualDate;
/**
* The observed date of the holiday.
*/
private final LocalDate observedDate;
/**
* The properties key to retrieve the description with.
*/
Expand All @@ -32,26 +38,68 @@ public final class Holiday implements Comparable<Holiday> {
* Constructs a holiday for a date using the provided properties key to
* retrieve the description with.
*
* @param date a {@link LocalDate} object.
* @param actualDate a {@link LocalDate} object.
* @param propertiesKey a {@link java.lang.String} object.
* @param type a {@link HolidayType} object.
*/
public Holiday(final LocalDate date, final String propertiesKey, final HolidayType type) {
public Holiday(final LocalDate actualDate, final String propertiesKey, final HolidayType type) {
this(actualDate, null, propertiesKey, type);
}

/**
* Constructs a holiday for a date using the provided properties key to
* retrieve the description with.
*
* @param actualDate a {@link LocalDate} object.
* @param observedDate a {@link LocalDate} object.
* @param propertiesKey a {@link java.lang.String} object.
* @param type a {@link HolidayType} object.
*/
public Holiday(final LocalDate actualDate, final LocalDate observedDate, final String propertiesKey, final HolidayType type) {
super();
this.type = type;
this.date = date;
this.actualDate = actualDate;
this.observedDate = observedDate;
this.propertiesKey = propertiesKey == null ? "" : propertiesKey;
}

/**
* Returns the calculated holiday date.
* <p>
* If the holiday is {@link de.focus_shift.jollyday.core.spi.Movable} and the holiday was moved, then:
* <ul>
* <li>the observed holiday date is given</li>
* <li>otherwise, the actual holiday date</li>
* </ul>
* <p>
* Getter for the field <code>date</code>.
* @return if holiday was moved the observed date, otherwise the actual date
*/
public LocalDate getDate() {
return Optional.ofNullable(observedDate).orElse(actualDate);
}

/**
* <p>
* Returns the actual date.
* <p>
* If you want the observed holiday date then use {@link #getObservedDate()}
* </p>
*
* @return the holiday date
* @return the actual holiday date
*/
public LocalDate getDate() {
return date;
public LocalDate getActualDate() {
return actualDate;
}

/**
* <p>
* Getter for the field <code>observedDate</code>.
* </p>
*
* @return the observed holiday date
*/
public LocalDate getObservedDate() {
return observedDate;
}

/**
Expand Down Expand Up @@ -86,31 +134,27 @@ public String getDescription(Locale locale) {

@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Holiday) {
final Holiday other = (Holiday) obj;
return other.date.equals(this.date) && other.propertiesKey.equals(this.propertiesKey) && type.equals(other.type);
if (obj == null || getClass() != obj.getClass()) {
return false;
}
return false;

final Holiday holiday = (Holiday) obj;
return Objects.equals(getDate(), holiday.getDate()) &&
Objects.equals(propertiesKey, holiday.propertiesKey) &&
type == holiday.type;
}

@Override
public int hashCode() {
if (hashCode == 0) {
int hash = 1;
hash = hash * 31 + date.hashCode();
hash = hash * 31 + propertiesKey.hashCode();
hash = hash * 31 + type.hashCode();
hashCode = hash;
hashCode = Objects.hash(actualDate, observedDate, propertiesKey, type);
}
return hashCode;
}

@Override
public String toString() {
return date.toString() + " (" + getDescription() + ")";
return actualDate.toString() + " (" + getDescription() + ")";
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@

public class CreateHoliday implements Function<Described, Holiday> {

private final LocalDate localDate;
private final LocalDate date;
private final LocalDate observedDate;

public CreateHoliday(LocalDate localDate) {
this.localDate = localDate;
public CreateHoliday(final LocalDate date) {
this(date, null);
}

public CreateHoliday(final LocalDate date, final LocalDate observedDate) {
this.date = date;
this.observedDate = observedDate;
}

@Override
public Holiday apply(final Described described) {
return new Holiday(localDate, described.descriptionPropertiesKey(), described.holidayType());
return new Holiday(date, observedDate, described.descriptionPropertiesKey(), described.holidayType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ public class ChristianHolidayParser implements HolidayParser {
public List<Holiday> parse(final Year year, final Holidays holidays) {
return holidays.christianHolidays().stream()
.filter(new ValidLimitation(year))
.map(ch -> {
LocalDate easterSunday = new CalculateEasterSunday(year).apply(ch.chronology());
switch (ch.type()) {
.map(christianHoliday -> {

LocalDate easterSunday = new CalculateEasterSunday(year).apply(christianHoliday.chronology());

switch (christianHoliday.type()) {
case EASTER:
break;
case CLEAN_MONDAY:
Expand Down Expand Up @@ -76,10 +78,10 @@ public List<Holiday> parse(final Year year, final Holidays holidays) {
easterSunday = easterSunday.plusDays(68);
break;
default:
throw new IllegalArgumentException("Unknown christian holiday type " + ch.type());
throw new IllegalArgumentException("Unknown christian holiday type " + christianHoliday.type());
}
easterSunday = new MoveDateRelative(easterSunday).apply(ch);
return new CreateHoliday(easterSunday).apply(ch);
final LocalDate movedChristianHoliday = new MoveDateRelative(easterSunday).apply(christianHoliday);
return new CreateHoliday(easterSunday, movedChristianHoliday).apply(christianHoliday);
})
.collect(toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,27 @@
class DescribedDateHolder {

private final LocalDate date;
private final LocalDate observedDate;
private final Described described;

public DescribedDateHolder(final Described described, final LocalDate date) {
DescribedDateHolder(final Described described, final LocalDate date) {
this(described, date, null);
}

DescribedDateHolder(final Described described, final LocalDate date, final LocalDate observedDate) {
this.date = date;
this.observedDate = observedDate;
this.described = described;
}

public LocalDate getDate() {
return date;
}

public LocalDate getObservedDate() {
return observedDate;
}

public Described getDescribed() {
return described;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public class FixedParser implements HolidayParser {
public List<Holiday> parse(final Year year, final Holidays holidays) {
return holidays.fixed().stream()
.filter(new ValidLimitation(year))
.map(fixed -> new DescribedDateHolder(fixed, new MoveDateRelative(new FixedToLocalDate(year).apply(fixed)).apply(fixed)))
.map(describedDateHolder -> new CreateHoliday(describedDateHolder.getDate()).apply(describedDateHolder.getDescribed()))
.map(fixed -> new DescribedDateHolder(fixed, new FixedToLocalDate(year).apply(fixed), new MoveDateRelative(new FixedToLocalDate(year).apply(fixed)).apply(fixed)))
.map(describedDateHolder -> new CreateHoliday(describedDateHolder.getDate(), describedDateHolder.getObservedDate()).apply(describedDateHolder.getDescribed()))
.collect(toList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ public List<Holiday> parse(final Year year, final Holidays holidays) {
}

return islamicHolidays
.map(date -> new MoveDateRelative(date).apply(islamicHoliday))
.map(date -> new CreateHoliday(date).apply(islamicHoliday));
.map(date -> new DescribedDateHolder(islamicHoliday, date, new MoveDateRelative(date).apply(islamicHoliday)))
.map(describedDateHolder -> new CreateHoliday(describedDateHolder.getDate(), describedDateHolder.getObservedDate()).apply(islamicHoliday));

})
.collect(toList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,20 @@ void testHolidayDescription() {
assertThat(holiday.getDescription(new Locale("nl"))).isEqualTo("Kerstmis");
}

@Test
void ensureToReturnObservedDateIfPresent() {
final LocalDate observedDate = LocalDate.of(2011, 2, 10);
final Holiday holiday = new Holiday(LocalDate.of(2011, 2, 2), observedDate, "CHRISTMAS", PUBLIC_HOLIDAY);
assertThat(holiday.getDate()).isEqualTo(observedDate);
}

@Test
void ensureToReturnActualDateIfObservedDateIsNotPresent() {
final LocalDate date = LocalDate.of(2011, 2, 2);
final Holiday holiday = new Holiday(date, "CHRISTMAS", PUBLIC_HOLIDAY);
assertThat(holiday.getDate()).isEqualTo(date);
}

@Test
void testHolidayEquals() {
final Holiday h1 = new Holiday(LocalDate.of(2011, 2, 2), "CHRISTMAS", PUBLIC_HOLIDAY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,7 @@ public DayOfWeek weekday() {
// ID_UL_ADHA_2 will be on a sunday in 2022
final List<Holiday> calculatedHoliday = sut.parse(Year.of(2022), holidays);
assertThat(calculatedHoliday.get(0).getDate().getDayOfWeek()).isEqualTo(DayOfWeek.MONDAY);
assertThat(calculatedHoliday.get(0).getActualDate().getDayOfWeek()).isEqualTo(DayOfWeek.SUNDAY);
assertThat(calculatedHoliday.get(0).getObservedDate().getDayOfWeek()).isEqualTo(DayOfWeek.MONDAY);
}
}

0 comments on commit 71327fa

Please sign in to comment.