Other answers here refer to Joda API. I want to do it using java.time
.
Suppose today's date is 26th Nov 2015-Thursday, when I add 2 business days to it, I want the result as Monday 30th Nov 2015.
I am working on my own implementation but it would be great if something already exists!
EDIT:
Is there a way to do it apart from looping over?
I was trying to derive a function like:
Y = f(X1,X2) where Y is actual number of days to add, X1 is number of business days to add, X2 is day of the week (1-Monday to 7-Sunday)
Then given X1
and X2
(derived from day of week of the date), we can find Y
and then use plusDays()
method of LocalDate
.
I have not been able to derive it so far, its not consistent. Can anyone confirm that looping over until desired number of workdays are added is the only way?
Checking a Weekend using LocalDateget(ChronoField. DAY_OF_WEEK) method returns an integer value in the range of 1 to 7. Each integer value represents a different weekday. 1 represents Monday, and so on 6 represents Saturday and 7 represents Sunday.
1. Adding Business Days. It uses two Predicate instances isHoliday and isWeekend . We repeatedly increment the LocalDate instance by 1 using the method plusDays() and check if the new date satisfies anyone of the given predicates.
The plusDays() method of a LocalDate class in Java is used to add the number of specified day in this LocalDate and return a copy of LocalDate. For example, 2018-12-31 plus one day would result in 2019-01-01. This instance is immutable and unaffected by this method call.
LocalDate – represents a date (year, month, day) LocalDateTime – same as LocalDate, but includes time with nanosecond precision. OffsetDateTime – same as LocalDateTime, but with time zone offset.
The following method adds days one by one, skipping weekends, for positive values of workdays
:
public LocalDate add(LocalDate date, int workdays) { if (workdays < 1) { return date; } LocalDate result = date; int addedDays = 0; while (addedDays < workdays) { result = result.plusDays(1); if (!(result.getDayOfWeek() == DayOfWeek.SATURDAY || result.getDayOfWeek() == DayOfWeek.SUNDAY)) { ++addedDays; } } return result; }
After some fiddling around, I came up with an algorithm to calculate the number of workdays to add or subtract.
/** * @param dayOfWeek * The day of week of the start day. The values are numbered * following the ISO-8601 standard, from 1 (Monday) to 7 * (Sunday). * @param businessDays * The number of business days to count from the day of week. A * negative number will count days in the past. * * @return The absolute (positive) number of days including weekends. */ public long getAllDays(int dayOfWeek, long businessDays) { long result = 0; if (businessDays != 0) { boolean isStartOnWorkday = dayOfWeek < 6; long absBusinessDays = Math.abs(businessDays); if (isStartOnWorkday) { // if negative businessDays: count backwards by shifting weekday int shiftedWorkday = businessDays > 0 ? dayOfWeek : 6 - dayOfWeek; result = absBusinessDays + (absBusinessDays + shiftedWorkday - 1) / 5 * 2; } else { // start on weekend // if negative businessDays: count backwards by shifting weekday int shiftedWeekend = businessDays > 0 ? dayOfWeek : 13 - dayOfWeek; result = absBusinessDays + (absBusinessDays - 1) / 5 * 2 + (7 - shiftedWeekend); } } return result; }
Usage Example:
LocalDate startDate = LocalDate.of(2015, 11, 26); int businessDays = 2; LocalDate endDate = startDate.plusDays(getAllDays(startDate.getDayOfWeek().getValue(), businessDays)); System.out.println(startDate + (businessDays > 0 ? " plus " : " minus ") + Math.abs(businessDays) + " business days: " + endDate); businessDays = -6; endDate = startDate.minusDays(getAllDays(startDate.getDayOfWeek().getValue(), businessDays)); System.out.println(startDate + (businessDays > 0 ? " plus " : " minus ") + Math.abs(businessDays) + " business days: " + endDate);
Example Output:
2015-11-26 plus 2 business days: 2015-11-30
2015-11-26 minus 6 business days: 2015-11-18
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With