JB Header
Java 8 - How to get last day / last working day of a month as LocalDate
This Java 8 coding tip first shows how to get the last day of a given month as a java.time.LocalDate instance. It then shows how to get the last working day of a month as a LocalDate when considering a 5-day work-week with Saturday and Sunday as weekly off days.

Java 8 code to get last day / last working day of a month
package com.javabrahman.java8.time;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.ChronoField;
import java.time.temporal.TemporalAdjusters;
public class LastDayOfMonth {
 public static void main(String args[]) {
  //1A. Last day of current month
  LocalDate lastDayofCurrentMonth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
  System.out.println("1A. Last day of the current month: "+
      lastDayofCurrentMonth.getDayOfWeek() + "," + lastDayofCurrentMonth);

  //1B. Last working day(LWD) of current month reusing lastDayOfCurrentMonth
  LocalDate lastWorkDayCurrentMonth=getLastWorkingDayOfMonth(lastDayofCurrentMonth);
  System.out.println("1B. Last working day of current month: "+
      lastWorkDayCurrentMonth.getDayOfWeek() + "," + lastWorkDayCurrentMonth);

  //2A. Last day of month for given date-"2017-01-13"
  LocalDate lastDayofMonthGivenDate = LocalDate.of(2017,01,13).with(TemporalAdjusters.lastDayOfMonth());
  System.out.println("2A. Last day of month for '2017-01-13': "+
      lastDayofMonthGivenDate.getDayOfWeek() + "," + lastDayofMonthGivenDate);

  //2B. LWD of month for date-"2017-01-13" reusing lastDayofMonthGivenDate
  LocalDate lastWorkDayGivenDate=getLastWorkingDayOfMonth(lastDayofMonthGivenDate);
  System.out.println("2B. Last working day of month for '2017-01-13': "+
    lastWorkDayGivenDate.getDayOfWeek() + "," + lastWorkDayGivenDate);

  //3A. Last day of month for year-month combination-"Apr, 2017"
  LocalDate lastDayofMonthYear = YearMonth.of(2017,04).atEndOfMonth();
  System.out.println("3A. Last day of month for 'Apr, 2017': "+
    lastDayofMonthYear.getDayOfWeek() + "," + lastDayofMonthYear);

  //3B. LWD of month for year-month combination-"Apr, 2017" reusing lastDayofMonthYear
    LocalDate lastWorkDayMonthYear=getLastWorkingDayOfMonth(lastDayofMonthYear);
    System.out.println("3B. Last working day of month for 'Apr, 2017': "+
      lastWorkDayMonthYear.getDayOfWeek() + "," + lastWorkDayMonthYear);
 }

 /**
  * Method calculates last working day for last day of month as input
  * @param lastDayOfMonth
  * @return LocalDate instance containing last working day
  */
 public static LocalDate getLastWorkingDayOfMonth(LocalDate lastDayOfMonth) {
   LocalDate lastWorkingDayofMonth;
   switch (DayOfWeek.of(lastDayOfMonth.get(ChronoField.DAY_OF_WEEK))) {
     case SATURDAY:
       lastWorkingDayofMonth = lastDayOfMonth.minusDays(1);
       break;
     case SUNDAY:
       lastWorkingDayofMonth = lastDayOfMonth.minusDays(2);
       break;
     default:
       lastWorkingDayofMonth = lastDayOfMonth;
   }
   return lastWorkingDayofMonth;
 }
}
 OUTPUT of the above code
1A. Last day of the current month:  SATURDAY,2016-12-31
1B. Last working day of current month:  FRIDAY,2016-12-30

2A. Last day of month for '2017-01-13':  TUESDAY,2017-01-31
2B. Last working day of month for '2017-01-13':  TUESDAY,2017-01-31

3A. Last day of month for 'Apr, 2017':  SUNDAY,2017-04-30
3B. Last working day of month for 'Apr, 2017':  FRIDAY,2017-04-28
Explanation of the code
  • getLastWorkingDayOfMonth() is a static method which takes as input the last day of the month and then based on that day being Saturday or Sunday, goes back 1 or 2 days respectively using the LocalDate.minusDays() method.
  • 1A. In the main() method - last day of the current month is calculated by first getting today’s date using LocalDate.now(). Then a pre-defined Temporal Adjuster for getting last day of month is used by applying with() method to get the desired last day of current month which is stored in lastDayofCurrentMonth variable and printed as 'SATURDAY,2016-12-31'.
  • 1B. lastDayofCurrentMonth, with value 'SATURDAY,2016-12-31', is passed to getLastWorkingDayOfMonth() method. Since, its a Saturday, the method does a minusDays(1) and returns 'FRIDAY,2016-12-30' as last working day which is printed.
  • 2A. LocalDate.of() method is used to create the LocalDate instance for '2017-01-13' to which is applied the with() method with TemporalAdjusters.lastDayOfMonth() to get the output - 'TUESDAY,2017-01-31'.
  • 2B. Since, 'TUESDAY,2017-01-31' is neither Saturday nor Sunday, getLastWorkingDayOfMonth() method uses the default condition to return the same day as last working day - which is then printed as output.
  • 3A. In this case the input is month-year i.e. 'Apr-2017'. YearMonth.of(2017,04) is used to instantiate an YearMonth instance on which the atEndOfMonth() method is invoked which returns the last day of the month - SUNDAY,2017-04-30.
  • 3B. Since, the last day of 'Apr-2017' is a Sunday, getLastWorkingDayOfMonth() does a minusDays(2) to it and returns 'FRIDAY,2017-04-28' as the last working day of the month - which is printed as the output.
NOTE - If there are any other scenarios, apart from end of month, for which you need to calculate dates for then please let me know in the comments below.