1 package org.nuiton.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import java.time.DayOfWeek;
26 import java.time.LocalDate;
27 import java.time.Year;
28 import java.time.temporal.ChronoUnit;
29 import java.util.HashSet;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Set;
33 import java.util.function.Function;
34
35
36
37
38
39
40
41 public class WorkdayUtil {
42
43 public static long computeWorday(LocalDate start, LocalDate end, Set<DayOfWeek> weekWorkday, Function<Year, List<LocalDate>> publicHoliday) {
44
45
46 Set<LocalDate> publicHolidays = new HashSet<>();
47 for (int year = start.getYear(), lastYear = end.getYear(); year <= lastYear; year++) {
48 publicHolidays.addAll(publicHoliday.apply(Year.of(year)));
49 }
50
51
52 long publicHolidayNumber = publicHolidays.stream()
53
54 .filter(d -> weekWorkday.contains(d.getDayOfWeek()))
55
56 .filter(d -> start.compareTo(d) * d.compareTo(end) >= 0)
57 .count();
58
59
60 long days = ChronoUnit.DAYS.between(start, end);
61 long week = days / DayOfWeek.values().length;
62
63 long result = week * weekWorkday.size();
64
65
66 LocalDate lastDays = end.minusDays(days % DayOfWeek.values().length);
67
68 while (lastDays.isBefore(end)) {
69 if (weekWorkday.contains(lastDays.getDayOfWeek())) {
70 result++;
71 }
72 lastDays = lastDays.plusDays(1);
73 }
74
75
76 result -= publicHolidayNumber;
77
78 return result;
79 }
80
81 public static class FrenchPublicHoliday implements Function<Year, List<LocalDate>> {
82
83 @Override
84 public List<LocalDate> apply(Year year) {
85 LocalDate easter = computeEaster(year);
86
87 List<LocalDate> result = new LinkedList<>();
88
89 result.add(computeEasterMonday(easter));
90 result.add(computeAscensionDay(easter));
91 result.add(computeWhitMonday(easter));
92 result.add(LocalDate.of(year.getValue(), 1, 1));
93 result.add(LocalDate.of(year.getValue(), 5, 1));
94 result.add(LocalDate.of(year.getValue(), 5, 8));
95 result.add(LocalDate.of(year.getValue(), 7, 14));
96 result.add(LocalDate.of(year.getValue(), 8, 15));
97 result.add(LocalDate.of(year.getValue(), 11, 1));
98 result.add(LocalDate.of(year.getValue(), 11, 11));
99 result.add(LocalDate.of(year.getValue(), 12, 25));
100
101 return result;
102 }
103 }
104
105
106
107
108
109
110
111 public static LocalDate computeEaster(Year year) {
112 int y = year.getValue();
113 int n = y % 19;
114
115 int c = y / 100;
116 int u = y % 100;
117
118 int s = c / 4;
119 int t = c % 4;
120
121 int p = (c + 8) / 25;
122 int q = (c - p + 1) / 3;
123
124 int e = (19 * n + c - s - q + 15) % 30;
125
126 int b = u / 4;
127 int d = u % 4;
128
129 int L = (32 + 2 * t + 2 * b - e - d) % 7;
130 int h = (n + 11 * e + 22 * L) / 451;
131
132 int m = (e + L - 7 * h + 114) / 31;
133 int j = (e + L - 7 * h + 114) % 31;
134
135 LocalDate easterMonday = LocalDate.of(y, m, j + 1);
136
137 return easterMonday;
138 }
139
140 public static LocalDate computeEasterMonday(LocalDate easter) {
141 LocalDate easterMonday = easter.plusDays(1);
142 return easterMonday;
143 }
144
145 public static LocalDate computeAscensionDay(LocalDate easter) {
146 LocalDate ascensionDay = easter.plusDays(39);
147 return ascensionDay;
148 }
149
150 public static LocalDate computeWhitMonday(LocalDate easter) {
151 LocalDate whitMonday = easter.plusDays(50);
152 return whitMonday;
153 }
154 }