[New] Added PeriodDuration.toMillis() with tests, etc.
This commit is contained in:
parent
704dc2b702
commit
bd0ea5cd27
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,56 @@
|
|||
package li.strolch.utils.time;
|
||||
|
||||
import static java.time.Period.between;
|
||||
|
||||
import java.time.Period;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import li.strolch.utils.dbc.DBC;
|
||||
|
||||
public class PeriodHelper {
|
||||
|
||||
public static double daysIn(PeriodDuration periodDuration) {
|
||||
return (daysIn(periodDuration.getPeriod()) + (periodDuration.getDuration().toHours() / 24.0));
|
||||
}
|
||||
|
||||
public static double daysIn(Period period) {
|
||||
return (period.getYears() * 365.0) + (period.getMonths() * 30.0) + period.getDays();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* being one month, and 365 days being one year.
|
||||
*
|
||||
* @param date
|
||||
* the date to shift
|
||||
* @param to
|
||||
* the date before which to stop shifting
|
||||
* @param periodDuration
|
||||
* the period shift in multiples by
|
||||
*
|
||||
* @return the shifted date
|
||||
*/
|
||||
public static ZonedDateTime shiftByMultipleOfPeriod(ZonedDateTime date, ZonedDateTime to,
|
||||
PeriodDuration periodDuration) {
|
||||
DBC.PRE.assertTrue("date must be before to!", date.isBefore(to));
|
||||
DBC.PRE.assertFalse("period duration may not be null!", periodDuration.isZero());
|
||||
Period between = between(date.toLocalDate(), to.toLocalDate());
|
||||
double daysInBetween = daysIn(between);
|
||||
double daysInPeriod = daysIn(periodDuration);
|
||||
long shifts = (long) (daysInBetween / daysInPeriod);
|
||||
if (shifts < 0)
|
||||
return date;
|
||||
|
||||
ZonedDateTime shiftedDate = date.plusDays((long) (shifts * daysInPeriod));
|
||||
|
||||
// see if we are close enough now
|
||||
between = between(shiftedDate.toLocalDate(), to.toLocalDate());
|
||||
daysInBetween = daysIn(between);
|
||||
shifts = (long) (daysInBetween / daysInPeriod);
|
||||
if (shifts < 2)
|
||||
return shiftedDate;
|
||||
|
||||
return shiftByMultipleOfPeriod(shiftedDate, to, periodDuration);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package li.strolch.utils.time;
|
||||
|
||||
import static java.time.ZoneId.systemDefault;
|
||||
import static li.strolch.utils.time.PeriodHelper.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PeriodHelperTest {
|
||||
|
||||
@Test
|
||||
public void shouldCalcHalfADay() {
|
||||
assertEquals(0.5, daysIn(PeriodDuration.parse("PT12H")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc1Day1() {
|
||||
assertEquals(1.0, daysIn(PeriodDuration.parse("P1D")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc1Day2() {
|
||||
assertEquals(1.0, daysIn(PeriodDuration.parse("PT24H")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc1AndAHalfDays() {
|
||||
assertEquals(1.5, daysIn(PeriodDuration.parse("PT36H")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc2Days1() {
|
||||
assertEquals(2.0, daysIn(PeriodDuration.parse("P2D")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc2Days2() {
|
||||
assertEquals(2.0, daysIn(PeriodDuration.parse("PT48H")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc2Days3() {
|
||||
assertEquals(2.0, daysIn(PeriodDuration.parse("P1DT24H")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc2AndAHalfDays0() {
|
||||
assertEquals(2.5, daysIn(PeriodDuration.parse("P1DT36H")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc3Days() {
|
||||
assertEquals(3.0, daysIn(PeriodDuration.parse("PT71H60M")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalc2Days23H() {
|
||||
assertEquals(2.958333333, daysIn(PeriodDuration.parse("PT71H")), 0.00001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalcDays() {
|
||||
assertEquals(30, daysIn(PeriodDuration.parse("P1M")), 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalcShiftDays1() {
|
||||
ZonedDateTime past = ZonedDateTime.now().minusDays(35);
|
||||
ZonedDateTime now = ZonedDateTime.now();
|
||||
PeriodDuration periodDuration = PeriodDuration.parse("P1M");
|
||||
ZonedDateTime shiftedDate = shiftByMultipleOfPeriod(past, now, periodDuration);
|
||||
|
||||
assertTrue(shiftedDate.isAfter(now.minusDays(29)));
|
||||
assertTrue(shiftedDate.isBefore(now));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalcShiftDays2() {
|
||||
ZonedDateTime past = ZonedDateTime
|
||||
.parse("2007-12-03T10:15:30+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(systemDefault()));
|
||||
ZonedDateTime now = ZonedDateTime.now();
|
||||
PeriodDuration periodDuration = PeriodDuration.parse("P1M");
|
||||
ZonedDateTime shiftedDate = shiftByMultipleOfPeriod(past, now, periodDuration);
|
||||
|
||||
// since P1M ist = 28 days, we have a rather inexact match, but it must certainly be before now() - P1M
|
||||
assertTrue(shiftedDate.isAfter(now.minusDays(56)));
|
||||
assertTrue(shiftedDate.isBefore(now.minusDays(28)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalcShiftDays3() {
|
||||
ZonedDateTime past = ZonedDateTime.now().minusDays(20);
|
||||
ZonedDateTime now = ZonedDateTime.now();
|
||||
PeriodDuration periodDuration = PeriodDuration.parse("P7D");
|
||||
ZonedDateTime shiftedDate = shiftByMultipleOfPeriod(past, now, periodDuration);
|
||||
|
||||
assertTrue(shiftedDate.isAfter(now.minusDays(9)));
|
||||
assertTrue(shiftedDate.isBefore(now));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCalcShiftDays4() {
|
||||
ZonedDateTime past = ZonedDateTime
|
||||
.parse("2007-12-03T10:15:30+01:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(systemDefault()));
|
||||
ZonedDateTime now = ZonedDateTime.now();
|
||||
PeriodDuration periodDuration = PeriodDuration.parse("P7D");
|
||||
ZonedDateTime shiftedDate = shiftByMultipleOfPeriod(past, now, periodDuration);
|
||||
|
||||
// since we are many years and months before now, and a year is 356 days and a month is 28 days, we inexact, but at least we must be a more than P7D before now
|
||||
assertTrue(shiftedDate.isBefore(now));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue