Reputation: 1773
public static String getLastWorkingDayOfPreviousMonth() {
LocalDate lastDayOfCurrentMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
LocalDate lastWorkingDayOfMonth;
switch (DayOfWeek.of(lastDayOfCurrentMonth.get(ChronoField.DAY_OF_WEEK))) {
case SATURDAY:
lastWorkingDayOfMonth = lastDayOfCurrentMonth.minusMonths(1);
break;
case SUNDAY:
lastWorkingDayOfMonth = lastDayOfCurrentMonth.minusMonths(2);
break;
default:
lastWorkingDayOfMonth = lastDayOfCurrentMonth;
}
return getFormattedDate(lastWorkingDayOfMonth);
}
The above gives last working day of the current month. How can I get the last working day of the Previous
month adjusting the above?
Upvotes: 5
Views: 10491
Reputation: 11
More simple and easy way without looping.
public static String getLastWorkingDayOfPreviousMonth() {
LocalDate localDate = LocalDate.now().minusMonths(1).with(TemporalAdjusters.lastDayOfMonth());
if (localDate.getDayOfWeek().getValue() > 5)
localDate = localDate.minusDays(localDate.getDayOfWeek().getValue() - 5);
return getFormattedDate(localDate);
}
Upvotes: 1
Reputation: 338211
LocalDate.now()
.withDayOfMonth( 1 )
.with(
org.threeten.extra.Temporals.previousWorkingDay()
)
previousWorkingDay
The ThreeTen-Extra project provides TemporalAdjuster
implementations for finding the next/previous weekday (non-Saturday/Sunday).
The last day of the previous month may be the target, a weekday. So our strategy is to get the first day of this month, the look back to get first previous working day.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z );
LocalDate firstOfMonth = today.withDayOfMonth( 1 ) ;
LocalDate lastWorkingDayOfPreviousMonth = firstOfMonth.with( org.threeten.extra.Temporals.previousWorkingDay() ) ;
Upvotes: 4
Reputation:
Another alternative is to use a java.time.YearMonth
to get the previous month. Then you get the last day of this month and adjust to previous Friday if it's in a weekend:
LocalDate lastDayPreviousMonth = YearMonth
// current year/month
.now()
// previous month
.minusMonths(1)
// last day of month
.atEndOfMonth();
DayOfWeek dayOfWeek = lastDayPreviousMonth.getDayOfWeek();
// check if it's weekend
if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) {
// adjust to previous friday
lastDayPreviousMonth = lastDayPreviousMonth.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY));
}
Running this code today (October 2nd 2017), it gives lastDayPreviousMonth
equals to 2017-09-29
.
PS: You're using minusMonths
in LocalDate
instances, which wont' always work like you want. Example, if I have a date in February 2017:
// Feb 15th 2017
LocalDate d = LocalDate.of(2017, 2, 15);
// adjust to last day of month (2017-02-28)
d = d.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(d.minusMonths(1)); // 2017-01-28
The last day of February 2017 is 28th, and when calling minusMonths(1)
, you get the same day (28th) at the previous month (January), which is not what you want (the last working day in January 2017 is 31st).
Using YearMonth
avoids this, because this class handles just the month and year, ignoring the day (so the minusMonths
doesn't suffer such effects). So you can easily go to the desired month, and then you can correctly get the last day using the atEndOfMonth()
method.
Upvotes: 12
Reputation: 1963
You can replace LocalDate.now().with(TemporalAdjusters.lastDayOfMonth())
in your code to LocalDate.now().minusMonth(1).with(TemporalAdjusters.lastDayOfMonth())
to get the last day of the previous month and after that keep on with the same logic to find the last working day of the month.
Upvotes: 0
Reputation: 2664
You can change your switch statement with the following code:
public static String getLastWorkingDayOfPreviousMonth() {
LocalDate lastDayOfCurrentMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
LocalDate lastWorkingDayOfMonth;
switch (lastDayOfCurrentMonth.minusMonths(1).getDayOfWeek()) {
case SATURDAY:
lastWorkingDayOfMonth = lastDayOfCurrentMonth.minusMonths(1).minusDays(1); // Here assgining second last day from previous month.
break;
case SUNDAY:
lastWorkingDayOfMonth = lastDayOfCurrentMonth.minusMonths(1).minusDays(2); // Here assgining third last day from previous month.
break;
default:
lastWorkingDayOfMonth = lastDayOfCurrentMonth.minusMonths(1); // Here assgining last day from previous month.
}
return lastWorkingDayOfMonth.toString();
}
Here, in this case I am calculating the last day of previous month (you can change the months before by changing the integer value in method minusMonths()
's parameter) with the weekends and in case of Weekends the Working day is changed accordingly.
Upvotes: 4
Reputation: 44293
Sometimes, the simple approach is better than a clever approach:
LocalDate lastWorkingDayOfMonth = LocalDate.now().withDayOfMonth(1);
do {
lastWorkingDayOfMonth = lastWorkingDayOfMonth.minusDays(1);
} while (lastWorkingDayOfMonth.getDayOfWeek() == DayOfWeek.SATURDAY ||
lastWorkingDayOfMonth.getDayOfWeek() == DayOfWeek.SUNDAY);
Upvotes: 4