[New] Added PeriodHelper.shiftMonths()
This commit is contained in:
parent
6eb3229a69
commit
0967b413ac
|
@ -28,6 +28,24 @@ public class PeriodHelper {
|
||||||
return (period.getYears() * 12.0) + (period.getMonths());
|
return (period.getYears() * 12.0) + (period.getMonths());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special method to add the given number of months to the given date and making sure that the day always stays the
|
||||||
|
* same if possible. I.e. If the given date has the 3. day, then this will also be so on the returned date. But for
|
||||||
|
* the day 29, 30 or 31 the date might change to 28 or 30, depending on the month on which the result lies.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* the date to shift
|
||||||
|
* @param nrOfMonths
|
||||||
|
* the number of months to shift the given date by
|
||||||
|
*
|
||||||
|
* @return the shifted date
|
||||||
|
*/
|
||||||
|
public static ZonedDateTime shiftMonths(ZonedDateTime date, int nrOfMonths) {
|
||||||
|
int selectedDayOfMonth = date.getDayOfMonth();
|
||||||
|
ZonedDateTime next = date.plusMonths(nrOfMonths);
|
||||||
|
return next.withDayOfMonth(Math.min(selectedDayOfMonth, next.toLocalDate().lengthOfMonth()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This special function allows us to shift a date by a multiple of the given {@link PeriodDuration} so that is
|
* This special function allows us to shift a date by a multiple of the given {@link PeriodDuration} so that is
|
||||||
* before the given to date. It does multiple tries to get as close as possible, due to the inexactness of 30 days
|
* before the given to date. It does multiple tries to get as close as possible, due to the inexactness of 30 days
|
||||||
|
|
|
@ -5,6 +5,8 @@ import static li.strolch.utils.time.PeriodHelper.*;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.Month;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
@ -87,6 +89,141 @@ public class PeriodHelperTest {
|
||||||
assertEquals(12, monthsIn(PeriodDuration.parse("P1Y")), 0.0);
|
assertEquals(12, monthsIn(PeriodDuration.parse("P1Y")), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPlusMonthsNormal() {
|
||||||
|
int expectedDay = 4;
|
||||||
|
|
||||||
|
ZonedDateTime date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
|
||||||
|
// increase by single months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = shiftMonths(date, 1);
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
// also when increase by multiple months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = shiftMonths(date, 4);
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPlusMonths28() {
|
||||||
|
int expectedDay = 28;
|
||||||
|
|
||||||
|
ZonedDateTime date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
|
||||||
|
// increase by single months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = shiftMonths(date, 1);
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
// also when increase by multiple months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = shiftMonths(date, 4);
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPlusMonths29() {
|
||||||
|
int expectedDay = 29;
|
||||||
|
|
||||||
|
ZonedDateTime date;
|
||||||
|
|
||||||
|
// increase by single months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
date = shiftMonths(date, i);
|
||||||
|
if (date.getMonth() == Month.FEBRUARY)
|
||||||
|
assertEquals(28, date.getDayOfMonth());
|
||||||
|
else
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
// also when increase by multiple months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
date = shiftMonths(date, i);
|
||||||
|
if (date.getMonth() == Month.FEBRUARY)
|
||||||
|
assertEquals(28, date.getDayOfMonth());
|
||||||
|
else
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPlusMonths30() {
|
||||||
|
int expectedDay = 30;
|
||||||
|
|
||||||
|
ZonedDateTime date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
|
||||||
|
// increase by single months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
date = shiftMonths(date, i);
|
||||||
|
if (date.getMonth() == Month.FEBRUARY)
|
||||||
|
assertEquals(28, date.getDayOfMonth());
|
||||||
|
else
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
|
||||||
|
// also when increase by multiple months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
date = shiftMonths(date, i);
|
||||||
|
if (date.getMonth() == Month.FEBRUARY)
|
||||||
|
assertEquals(28, date.getDayOfMonth());
|
||||||
|
else
|
||||||
|
assertEquals(expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldPlusMonths31() {
|
||||||
|
int expectedDay = 31;
|
||||||
|
|
||||||
|
ZonedDateTime date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
assertEquals(date.getMonth().name(), expectedDay, date.getDayOfMonth());
|
||||||
|
|
||||||
|
// increase by single months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
date = shiftMonths(date, i);
|
||||||
|
if (date.getMonth() == Month.FEBRUARY) {
|
||||||
|
assertEquals(date.getMonth().name(), 28, date.getDayOfMonth());
|
||||||
|
} else if (date.getMonth() == Month.APRIL //
|
||||||
|
|| date.getMonth() == Month.JUNE //
|
||||||
|
|| date.getMonth() == Month.SEPTEMBER //
|
||||||
|
|| date.getMonth() == Month.NOVEMBER) {
|
||||||
|
assertEquals(date.getMonth().name(), 30, date.getDayOfMonth());
|
||||||
|
} else {
|
||||||
|
assertEquals(date.getMonth().name(), expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// also when increase by multiple months
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
date = LocalDate.of(2001, Month.JANUARY, expectedDay).atStartOfDay(systemDefault());
|
||||||
|
date = shiftMonths(date, i);
|
||||||
|
if (date.getMonth() == Month.FEBRUARY) {
|
||||||
|
assertEquals(date.getMonth().name(), 28, date.getDayOfMonth());
|
||||||
|
} else if (date.getMonth() == Month.APRIL //
|
||||||
|
|| date.getMonth() == Month.JUNE //
|
||||||
|
|| date.getMonth() == Month.SEPTEMBER //
|
||||||
|
|| date.getMonth() == Month.NOVEMBER) {
|
||||||
|
assertEquals(date.getMonth().name(), 30, date.getDayOfMonth());
|
||||||
|
} else {
|
||||||
|
assertEquals(date.getMonth().name(), expectedDay, date.getDayOfMonth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void shouldCalcShiftDays1() {
|
public void shouldCalcShiftDays1() {
|
||||||
ZonedDateTime past = ZonedDateTime.now().minusDays(35);
|
ZonedDateTime past = ZonedDateTime.now().minusDays(35);
|
||||||
|
|
Loading…
Reference in New Issue