diff --git a/core-java-modules/core-java-date-operations-4/README.md b/core-java-modules/core-java-date-operations-4/README.md new file mode 100644 index 0000000000..e023a5ca53 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/README.md @@ -0,0 +1,6 @@ +## Core Date Operations (Part 4) +This module contains articles about date operations in Java. + +### Relevant Articles: + + diff --git a/core-java-modules/core-java-date-operations-4/pom.xml b/core-java-modules/core-java-date-operations-4/pom.xml new file mode 100644 index 0000000000..5153b4b354 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + core-java-date-operations-4 + core-java-date-operations-4 + + + + org.apache.maven.plugins + maven-compiler-plugin + + 11 + 11 + + + + + jar + + + com.baeldung.core-java-modules + core-java-modules + 0.0.1-SNAPSHOT + + + + + joda-time + joda-time + ${joda-time.version} + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + 2.12.5 + + + \ No newline at end of file diff --git a/core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java b/core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java new file mode 100644 index 0000000000..ded8f9bc13 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/src/main/java/com/baeldung/calculateweekdays/CalculateWeekdays.java @@ -0,0 +1,46 @@ +package com.baeldung.calculateweekdays; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAdjusters; +import java.util.Arrays; + +public class CalculateWeekdays { + + public long getWorkingDaysWithStream(LocalDate start, LocalDate end){ + return start.datesUntil(end) + .map(LocalDate::getDayOfWeek) + .filter(day -> !Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY).contains(day)) + .count(); + } + + public long getWorkingDaysWithoutStream(LocalDate start, LocalDate end) { + boolean startOnWeekend = false; + + // If starting at the weekend, move to following Monday + if(start.getDayOfWeek().getValue() > 5){ + start = start.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); + startOnWeekend = true; + } + boolean endOnWeekend = false; + // If ending at the weekend, move to previous Friday + if(end.getDayOfWeek().getValue() > 5){ + end = end.with(TemporalAdjusters.previous(DayOfWeek.FRIDAY)); + endOnWeekend = true; + } + // Cover case where starting on Saturday and ending following Sunday + if(start.isAfter(end)){ + return 0; + } + // Get total weeks + long weeks = ChronoUnit.WEEKS.between(start, end); + + long addValue = startOnWeekend || endOnWeekend ? 1 : 0; + + // Add on days that did not make up a full week + return ( weeks * 5 ) + ( end.getDayOfWeek().getValue() - start.getDayOfWeek().getValue() ) + addValue; + } + + +} diff --git a/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java new file mode 100644 index 0000000000..4a14b6bb99 --- /dev/null +++ b/core-java-modules/core-java-date-operations-4/src/test/java/com/baeldung/calculateweekdays/CalculateWeekdaysUnitTest.java @@ -0,0 +1,83 @@ +package com.baeldung.calculateweekdays; + +import static junit.framework.TestCase.assertEquals; + +import java.time.LocalDate; + +import org.junit.Test; + +public class CalculateWeekdaysUnitTest { + + // Start Saturday end following Sunday (answer is 0) + LocalDate startTomorrow = LocalDate.of(2023, 12, 2); + LocalDate endTomorrow = LocalDate.of(2023, 12, 3); + + // Three week gap with midweek start and finish (answer is 17) + LocalDate startThreeWeeks = LocalDate.of(2023, 11, 28); + LocalDate endThreeWeeks = LocalDate.of(2023, 12, 21); + + // Three week gap with midweek start and weekend finish (answer is 17) + LocalDate startThreeWeeks2 = LocalDate.of(2023, 11, 6); + LocalDate endThreeWeeks2 = LocalDate.of(2023, 12, 30); + + // Week gap start and end on weekend (answer is 40) + LocalDate startThreeWeeksWeekend = LocalDate.of(2023, 12, 2); + LocalDate endThreeWeeksWeekend = LocalDate.of(2023, 12, 9); + + @Test + public void givenTwoDaysOnSameWeekend_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startTomorrow, endTomorrow); + assertEquals(0, result); + } + + @Test + public void givenTwoDaysOnSameWeekend_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startTomorrow, endTomorrow); + assertEquals(0, result); + } + + @Test + public void givenAThreeWeekGapMidweekDates_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeks, endThreeWeeks); + assertEquals(17, result); + } + + @Test + public void givenAThreeWeekGapMidweekDates_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeks, endThreeWeeks); + assertEquals(17, result); + } + + @Test + public void givenThreeWeekGapMidweekAndWeekendDates_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeksWeekend, endThreeWeeksWeekend); + assertEquals(5, result); + } + + @Test + public void givenThreeWeekGapMidweekAndWeekendDates_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeksWeekend, endThreeWeeksWeekend); + assertEquals(5, result); + } + + @Test + public void givenThreeWeekGapWeekendDates_whenUsingStreams_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithStream(startThreeWeeks2, endThreeWeeks2); + assertEquals(40, result); + } + + @Test + public void givenThreeWeekGapWeekendDates_whenUsingMaths_calculateWeekdays(){ + CalculateWeekdays c = new CalculateWeekdays(); + long result = c.getWorkingDaysWithoutStream(startThreeWeeks2, endThreeWeeks2); + assertEquals(40, result); + } + +}