Reputation: 1783
I have the following Holiday
class:
public class Holiday {
private int day;
private int month;
public Holiday(GregorianCalendar calendar) {
this.day = calendar.get(GregorianCalendar.DAY_OF_MONTH);
this.month = calendar.get(GregorianCalendar.MONTH) + 1;
}
}
enum Day:
public enum Day {
SATURDAY(6), SUNDAY(7);
private int index;
Day(int index) {
this.index = index;
}
public int getIndex() {
return index;
}
}
public class DateTool {
private static final String DATE_FORMAT = "yyyy_MM_dd";
public DateTool() {
super();
}
public static String getPreviousWorkingDay(List<Holiday> listOfHolidays) {
//derive the last working day that is not saturday/sunday
}
public static String parseDate(Date date) {
return new SimpleDateFormat(DATE_FORMAT).format(date);
}
public static boolean isSunday(LocalDateTime date) {
return date.getDayOfWeek().getValue() == Day.SUNDAY.getIndex();
}
public static boolean isSaturday(LocalDateTime date) {
return date.getDayOfWeek().getValue() == Day.SATURDAY.getIndex();
}
}
Given I have list
of holidays
, how can I work out and return the last previous working day in getPreviousWorkingDay(...)
method which will exclude saturday and sunday?
I am trying to derive the last file date to look for so something like this I am trying to work out
if (todayIsHoliday(listOfHolidays)) {
getPreviousWorkingDay(listOfHolidays);
}
so If current day is holiday, look at the last date which is not holiday and return as string formatted.
I’m unsure as to how to look back. Please note list of holidays is not only Saturday and Sunday. They are country holidays e.g Chinese New Year etc.
I’m using java 8 for this so any refactorings or improvements is welcome :)
Upvotes: 2
Views: 2098
Reputation: 338604
The Answer by Ole V.V. is good. Here’s a couple more tips to augment that approach.
You can define your weekend as a EnumSet
of DayOfWeek
objects for Saturday and Sunday. An EnumSet
is a highly efficient implementation of Set
for holding enum objects. Takes very little memory, and has very fast execution.
Set<DayOfWeek> weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY ) ;
Then ask if a date’s day-of-week is contained in that set.
boolean isWeekend = weekend.contains( localDate.getDayOfWeek() ) ;
The ThreeTen-Extra project extends the java.time with additional features. Among this features is a TemporalAdjuster
for moving to the next/previous date while skipping any Saturday or Sunday.
LocalDate nextWeekDay = org.threeten.extra.Temporals.nextWorkingDay( localDate ) ;
TemporalAdjuster
You can write your own implementation of TemporalAdjuster
to encapsulate all your weekend + holiday logic in one place that can be easily reused with a simple compact call.
LocalDate nextBusinessDay = localDate.with( com.example.Temporals.nextBusinessDay() ) ;
Upvotes: 3
Reputation: 86276
private static final DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("uuuu_MM_dd");
public static String getPreviousWorkingDay(List<MonthDay> listOfHolidays) {
LocalDate workingDay = LocalDate.now(ZoneId.of("Pacific/Easter")).minusDays(1);
while (workingDay.getDayOfWeek().equals(DayOfWeek.SATURDAY)
|| workingDay.getDayOfWeek().equals(DayOfWeek.SUNDAY)
|| listOfHolidays.contains(MonthDay.from(workingDay))) {
workingDay = workingDay.minusDays(1);
}
return workingDay.format(dateFormatter);
}
I am using java.time
, the modern Java date and time API, and as mentioned in a comment I recommend you do the same. Let’s see the above method in action:
System.out.println(getPreviousWorkingDay(Collections.emptyList()));
// Let’s say Valentin’s day is a holiday
System.out.println(getPreviousWorkingDay(List.of(MonthDay.of(Month.FEBRUARY, 14))));
// And so are Lent Monday and the death day of Danish would-be king Henrik
System.out.println(getPreviousWorkingDay(List.of(MonthDay.of(Month.FEBRUARY, 12),
MonthDay.of(Month.FEBRUARY, 13), MonthDay.of(Month.FEBRUARY, 14))));
Today this printed:
2018_02_14
2018_02_13
2018_02_09
(I am cheating a bit since Lent Monday is not the same day every year; but I figure it’s not a requirement to take such holidays into account.)
Since determining today’s date is a time zone sensitive operation, please substitute your desired time zone if it didn’t happen to be the Easter Island time zone. Edit: In Java 8 use Arrays.asList()
instead of the Java 9 List.of()
.
Link: Oracle tutorial: Date Time explaining how to use java.time
.
Upvotes: 4