diff --git a/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java new file mode 100644 index 0000000000..f32549730d --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/main/java/com/baeldung/monthintervalbetweentwodates/MonthInterval.java @@ -0,0 +1,37 @@ +package com.baeldung.monthintervalbetweentwodates; + +import java.util.Calendar; +import java.util.Date; + +public class MonthInterval { + + public int monthsBetween(Date startDate, Date endDate) { + if (startDate == null || endDate == null) { + throw new IllegalArgumentException("Both startDate and endDate must be provided"); + } + Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(startDate); + int startDateTotalMonths = 12 * startCalendar.get(Calendar.YEAR) + startCalendar.get(Calendar.MONTH); + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(endDate); + int endDateTotalMonths = 12 * endCalendar.get(Calendar.YEAR) + endCalendar.get(Calendar.MONTH); + return endDateTotalMonths - startDateTotalMonths; + } + + public int monthsBetweenWithDayValue(Date startDate, Date endDate) { + if (startDate == null || endDate == null) { + throw new IllegalArgumentException("Both startDate and endDate must be provided"); + } + Calendar startCalendar = Calendar.getInstance(); + startCalendar.setTime(startDate); + int startDayOfMonth = startCalendar.get(Calendar.DAY_OF_MONTH); + int startDateTotalMonths = 12 * startCalendar.get(Calendar.YEAR) + startCalendar.get(Calendar.MONTH); + Calendar endCalendar = Calendar.getInstance(); + endCalendar.setTime(endDate); + int endDayOfMonth = endCalendar.get(Calendar.DAY_OF_MONTH); + int endDateTotalMonths = 12 * endCalendar.get(Calendar.YEAR) + endCalendar.get(Calendar.MONTH); + + return (startDayOfMonth > endDayOfMonth) ? (endDateTotalMonths - startDateTotalMonths) - 1 : (endDateTotalMonths - startDateTotalMonths); + } + +} diff --git a/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java new file mode 100644 index 0000000000..2cd5638cc8 --- /dev/null +++ b/core-java-modules/core-java-8-datetime-2/src/test/java/com/baeldung/monthintervalbetweentwodates/MonthIntervalUnitTest.java @@ -0,0 +1,93 @@ +package com.baeldung.monthintervalbetweentwodates; + +import org.joda.time.DateTime; +import org.joda.time.Months; +import org.junit.jupiter.api.Test; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Period; +import java.time.YearMonth; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MonthIntervalUnitTest { + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingJodaTime_thenReturnMonthsDifference() { + DateTime firstDate = new DateTime(2023, 5, 25, 0, 0); + DateTime secondDate = new DateTime(2023, 11, 23, 0, 0); + + int monthsBetween = Months.monthsBetween(firstDate, secondDate) + .getMonths(); + assertEquals(5, monthsBetween); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingJodaTimeSetTimeToFirstDayOfMonth_thenReturnMonthsDifference() { + DateTime firstDate = new DateTime(2023, 5, 25, 0, 0).withDayOfMonth(1); + DateTime secondDate = new DateTime(2023, 11, 23, 0, 0).withDayOfMonth(1); + + int monthsBetween = Months.monthsBetween(firstDate, secondDate) + .getMonths(); + assertEquals(6, monthsBetween); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingPeriodClass_thenReturnMonthsDifference() { + Period diff = Period.between(LocalDate.parse("2023-05-25"), LocalDate.parse("2023-11-23")); + assertEquals(5, diff.getMonths()); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingPeriodClassAndAdjsutingDatesToFirstDayOfTheMonth_thenReturnMonthsDifference() { + Period diff = Period.between(LocalDate.parse("2023-05-25") + .withDayOfMonth(1), LocalDate.parse("2023-11-23") + .withDayOfMonth(1)); + assertEquals(6, diff.getMonths()); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingChronoUnitAndYearMonth_thenReturnMonthsDifference() { + long diff = ChronoUnit.MONTHS.between(YearMonth.from(LocalDate.parse("2023-05-25")), LocalDate.parse("2023-11-23")); + assertEquals(6, diff); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingChronoUnitEnum_thenReturnMonthsDifference() { + long monthsBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2023-05-25"), LocalDate.parse("2023-11-23")); + assertEquals(5, monthsBetween); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingChronoUnitEnumdSetTimeToFirstDayOfMonth_thenReturnMonthsDifference() { + long monthsBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2023-05-25") + .withDayOfMonth(1), LocalDate.parse("2023-11-23") + .withDayOfMonth(1)); + assertEquals(6, monthsBetween); + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingLegacyDateApi_thenReturnMonthsDifference() throws ParseException { + MonthInterval monthDifference = new MonthInterval(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = sdf.parse("2016-05-31"); + Date endDate = sdf.parse("2016-11-30"); + int monthsBetween = monthDifference.monthsBetween(startDate, endDate); + assertEquals(6, monthsBetween); + + } + + @Test + void givenTwoDates_whenCalculatingMonthsBetweenUsingLegacyDateApiDayValueConsidered_thenReturnMonthsDifference() throws ParseException { + MonthInterval monthDifference = new MonthInterval(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date startDate = sdf.parse("2016-05-31"); + Date endDate = sdf.parse("2016-11-28"); + int monthsBetween = monthDifference.monthsBetweenWithDayValue(startDate, endDate); + assertEquals(5, monthsBetween); + } +}