branch develop updated (75f28e8 -> c3bc8c3)
This is an automated email from the git hooks/post-receive script. New change to branch develop in repository nuiton-utils. See https://gitlab.nuiton.org/nuiton/nuiton-utils.git omits 75f28e8 Ajout du calcul de jours ouvrés (avec par l'implantation pour les vacances pour la france) new c3bc8c3 Ajout du calcul de jours ouvrés (avec par l'implantation pour les vacances pour la france) This update added new revisions after undoing existing revisions. That is to say, some revisions that were in the old version of the branch are not in the new version. This situation occurs when a user --force pushes a change and generates a repository containing something like this: * -- * -- B -- O -- O -- O (75f28e8) \ N -- N -- N refs/heads/develop (c3bc8c3) You should already have received notification emails for all of the O revisions, and so the following emails describe only the N revisions from the common base, B. Any revisions marked "omits" are not gone; other references still refer to them. Any revisions marked "discards" are gone forever. The 1 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit c3bc8c32f06ad094cbed48ab8203011c2ac3b975 Author: Benjamin <poussin@codelutin.com> Date: Fri Sep 7 17:06:04 2018 +0200 Ajout du calcul de jours ouvrés (avec par l'implantation pour les vacances pour la france) Summary of changes: src/main/java/org/nuiton/util/WorkdayUtil.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch develop in repository nuiton-utils. See https://gitlab.nuiton.org/nuiton/nuiton-utils.git commit c3bc8c32f06ad094cbed48ab8203011c2ac3b975 Author: Benjamin <poussin@codelutin.com> Date: Fri Sep 7 17:06:04 2018 +0200 Ajout du calcul de jours ouvrés (avec par l'implantation pour les vacances pour la france) --- src/main/java/org/nuiton/util/WorkdayUtil.java | 132 +++++++++++++++++++++ src/test/java/org/nuiton/util/WorkdayUtilTest.java | 77 ++++++++++++ 2 files changed, 209 insertions(+) diff --git a/src/main/java/org/nuiton/util/WorkdayUtil.java b/src/main/java/org/nuiton/util/WorkdayUtil.java new file mode 100644 index 0000000..271590e --- /dev/null +++ b/src/main/java/org/nuiton/util/WorkdayUtil.java @@ -0,0 +1,132 @@ +package org.nuiton.util; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.Year; +import java.time.temporal.ChronoUnit; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +/** + * Permet de calculer le nombre de jour ouvré entre deux dates. + * + * du 3 au 3 donne 0. + * du 3 au 4 donne 1 (si 3 n'est pas un jour fermé) + */ +public class WorkdayUtil { + + public static long computeWorday(LocalDate start, LocalDate end, Set<DayOfWeek> weekWorkday, Function<Year, List<LocalDate>> publicHoliday) { + + // recherche tous les jours fériés des années entre les deux dates + Set<LocalDate> publicHolidays = new HashSet<>(); + for (int year = start.getYear(), lastYear = end.getYear(); year <= lastYear; year++) { + publicHolidays.addAll(publicHoliday.apply(Year.of(year))); + } + + // calcul le nombre de jour férié dans l'interval + long publicHolidayNumber = publicHolidays.stream() + // On garde que des jours fériés qui tombe un jour ouvré + .filter(d -> weekWorkday.contains(d.getDayOfWeek())) + // On garde que des jours fériés qui sont dans l'interval de date + .filter(d -> start.compareTo(d) * d.compareTo(end) >= 0) + .count(); + + // calcul le nombre de jour ouvré en semaine pleine + long days = ChronoUnit.DAYS.between(start, end); + long week = days / DayOfWeek.values().length; + + long result = week * weekWorkday.size(); + + // on calcul le nombre de jour ouvré de la dernière semaine non pleine + LocalDate lastDays = end.minusDays(days % DayOfWeek.values().length); + + while (lastDays.isBefore(end)) { + if (weekWorkday.contains(lastDays.getDayOfWeek())) { + result++; + } + lastDays = lastDays.plusDays(1); + } + + // on retranche les jours fériés + result -= publicHolidayNumber; + + return result; + } + + public static class FrenchPublicHoliday implements Function<Year, List<LocalDate>> { + + @Override + public List<LocalDate> apply(Year year) { + LocalDate easter = computeEaster(year); + + List<LocalDate> result = new LinkedList<>(); + + result.add(computeEasterMonday(easter)); + result.add(computeAscensionDay(easter)); + result.add(computeWhitMonday(easter)); + result.add(LocalDate.of(year.getValue(), 1, 1)); + result.add(LocalDate.of(year.getValue(), 5, 1)); + result.add(LocalDate.of(year.getValue(), 5, 8)); + result.add(LocalDate.of(year.getValue(), 7, 14)); + result.add(LocalDate.of(year.getValue(), 8, 15)); + result.add(LocalDate.of(year.getValue(), 11, 1)); + result.add(LocalDate.of(year.getValue(), 11, 11)); + result.add(LocalDate.of(year.getValue(), 12, 25)); + + return result; + } + } + + /** + * Calcul fait par la méthode de Butcher-Meeus (valide si année ≥ 1583) + * + * @param year l'année pour lequel on souhaite calculer le dimanche de paques + * @return la date du dimanche paques + */ + public static LocalDate computeEaster(Year year) { + int y = year.getValue(); + int n = y % 19; + + int c = y / 100; + int u = y % 100; + + int s = c / 4; + int t = c % 4; + + int p = (c + 8) / 25; + int q = (c - p + 1) / 3; + + int e = (19 * n + c - s - q + 15) % 30; + + int b = u / 4; + int d = u % 4; + + int L = (32 + 2 * t + 2 * b - e - d) % 7; + int h = (n + 11 * e + 22 * L) / 451; + + int m = (e + L - 7 * h + 114) / 31; + int j = (e + L - 7 * h + 114) % 31; + + LocalDate easterMonday = LocalDate.of(y, m, j + 1); + + return easterMonday; + } + + public static LocalDate computeEasterMonday(LocalDate easter) { + LocalDate easterMonday = easter.plusDays(1); + return easterMonday; + } + + public static LocalDate computeAscensionDay(LocalDate easter) { + LocalDate ascensionDay = easter.plusDays(39); + return ascensionDay; + } + + public static LocalDate computeWhitMonday(LocalDate easter) { + LocalDate whitMonday = easter.plusDays(50); + return whitMonday; + } +} diff --git a/src/test/java/org/nuiton/util/WorkdayUtilTest.java b/src/test/java/org/nuiton/util/WorkdayUtilTest.java new file mode 100644 index 0000000..139cb61 --- /dev/null +++ b/src/test/java/org/nuiton/util/WorkdayUtilTest.java @@ -0,0 +1,77 @@ +package org.nuiton.util; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.Year; +import java.util.EnumSet; +import java.util.Set; + +public class WorkdayUtilTest { + + @Test + public void testEasterAscensionDayWit() { + LocalDate easter2006 = WorkdayUtil.computeEaster(Year.of(2006)); + Assert.assertEquals(LocalDate.of(2006, 4, 16), easter2006); + + LocalDate easter2018 = WorkdayUtil.computeEaster(Year.of(2018)); + Assert.assertEquals(LocalDate.of(2018, 4, 2), WorkdayUtil.computeEasterMonday(easter2018)); + Assert.assertEquals(LocalDate.of(2018, 5, 10), WorkdayUtil.computeAscensionDay(easter2018)); + Assert.assertEquals(LocalDate.of(2018, 5, 21), WorkdayUtil.computeWhitMonday(easter2018)); + + LocalDate easter2019 = WorkdayUtil.computeEaster(Year.of(2019)); + Assert.assertEquals(LocalDate.of(2019, 4, 22), WorkdayUtil.computeEasterMonday(easter2019)); + Assert.assertEquals(LocalDate.of(2019, 5, 30), WorkdayUtil.computeAscensionDay(easter2019)); + Assert.assertEquals(LocalDate.of(2019, 6, 10), WorkdayUtil.computeWhitMonday(easter2019)); + + LocalDate easter2020 = WorkdayUtil.computeEaster(Year.of(2020)); + Assert.assertEquals(LocalDate.of(2020, 4, 13), WorkdayUtil.computeEasterMonday(easter2020)); + Assert.assertEquals(LocalDate.of(2020, 5, 21), WorkdayUtil.computeAscensionDay(easter2020)); + Assert.assertEquals(LocalDate.of(2020, 6, 1), WorkdayUtil.computeWhitMonday(easter2020)); + } + + @Test + public void testWorkDays() { + Set<DayOfWeek> weekWorkday = EnumSet.of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.WEDNESDAY, DayOfWeek.THURSDAY, DayOfWeek.FRIDAY); + WorkdayUtil.FrenchPublicHoliday publicHoliday = new WorkdayUtil.FrenchPublicHoliday(); + + { + LocalDate start = LocalDate.of(2017, 12, 22); + LocalDate end = LocalDate.of(2017, 12, 22); + + Assert.assertEquals(0, WorkdayUtil.computeWorday(start, end, weekWorkday, publicHoliday)); + } + { + LocalDate start = LocalDate.of(2017, 12, 22); + LocalDate end = LocalDate.of(2017, 12, 25); + + Assert.assertEquals(0, WorkdayUtil.computeWorday(start, end, weekWorkday, publicHoliday)); + } + { + LocalDate start = LocalDate.of(2017, 12, 22); + LocalDate end = LocalDate.of(2017, 12, 26); + + Assert.assertEquals(1, WorkdayUtil.computeWorday(start, end, weekWorkday, publicHoliday)); + } + { + LocalDate start = LocalDate.of(2017, 12, 22); + LocalDate end = LocalDate.of(2018, 1, 6); + + Assert.assertEquals(9, WorkdayUtil.computeWorday(start, end, weekWorkday, publicHoliday)); + } + { + LocalDate start = LocalDate.of(2017, 12, 25); + LocalDate end = LocalDate.of(2017, 12, 26); + + Assert.assertEquals(0, WorkdayUtil.computeWorday(start, end, weekWorkday, publicHoliday)); + } + { + LocalDate start = LocalDate.of(2017, 12, 25); + LocalDate end = LocalDate.of(2018, 1, 26); + + Assert.assertEquals(22, WorkdayUtil.computeWorday(start, end, weekWorkday, publicHoliday)); + } + } +} -- To stop receiving notification emails like this one, please contact nuiton.org SCM administrator <admin+scm@nuiton.org>.
participants (1)
-
nuiton.org scm