diff --git a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DateTimeType.java b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DateTimeType.java index 132ede449ba..fe9c54567c3 100644 --- a/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DateTimeType.java +++ b/bundles/org.openhab.core/src/main/java/org/openhab/core/library/types/DateTimeType.java @@ -20,6 +20,7 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoUnit; import java.time.zone.ZoneRulesException; import java.util.Locale; @@ -37,6 +38,7 @@ * @author Wouter Born - increase parsing and formatting precision * @author Laurent Garnier - added methods toLocaleZone and toZone * @author Gaël L'hopital - added ability to use second and milliseconds unix time + * @author Gaël L'hopital - added isToday, isTomorrow, isYesterday, sameDay */ @NonNullByDefault public class DateTimeType implements PrimitiveType, State, Command { @@ -248,4 +250,85 @@ private ZonedDateTime parse(String value) throws DateTimeParseException { return date; } + + public boolean isToday() { + return sameDay(ZonedDateTime.now()); + } + + public boolean isTomorrow() { + return sameDay(ZonedDateTime.now().plusDays(1)); + } + + public boolean isYesterday() { + return sameDay(ZonedDateTime.now().minusDays(1)); + } + + public boolean sameDay(DateTimeType other) { + return sameDay(other.zonedDateTime); + } + + public boolean sameDay(ZonedDateTime other) { + return zonedDateTime.truncatedTo(ChronoUnit.DAYS) + .isEqual(other.withZoneSameInstant(zonedDateTime.getZone()).truncatedTo(ChronoUnit.DAYS)); + } + + public DateTimeType toToday() { + return shiftDaysFromToday(0); + } + + public DateTimeType toTomorrow() { + return shiftDaysFromToday(1); + } + + public DateTimeType toYesterday() { + return shiftDaysFromToday(-1); + } + + private DateTimeType shiftDaysFromToday(int days) { + ZonedDateTime now = ZonedDateTime.now().plusDays(days); + return new DateTimeType(zonedDateTime.withYear(now.getYear()).withMonth(now.getMonthValue()) + .withDayOfMonth(now.getDayOfMonth())); + } + + public boolean isBefore(DateTimeType other) { + return zonedDateTime.isBefore(other.zonedDateTime); + } + + public boolean isAfter(DateTimeType other) { + return zonedDateTime.isAfter(other.zonedDateTime); + } + + public boolean isBeforeDate(DateTimeType other) { + return isBeforeDate(other.zonedDateTime); + } + + public boolean isBeforeDate(ZonedDateTime other) { + return zonedDateTime.truncatedTo(ChronoUnit.DAYS).isBefore(other.truncatedTo(ChronoUnit.DAYS)); + } + + public boolean isBeforeTime(DateTimeType other) { + return isBeforeTime(other.zonedDateTime); + } + + public boolean isBeforeTime(ZonedDateTime other) { + return zonedDateTime.withYear(other.getYear()).withMonth(other.getMonthValue()) + .withDayOfMonth(other.getDayOfMonth()).isBefore(other); + } + + public boolean isAfterTime(DateTimeType other) { + return isAfterTime(other.zonedDateTime); + } + + public boolean isAfterTime(ZonedDateTime other) { + return zonedDateTime.withYear(other.getYear()).withMonth(other.getMonthValue()) + .withDayOfMonth(other.getDayOfMonth()).isAfter(other); + } + + public boolean isAfterDate(DateTimeType other) { + return isAfterDate(other.zonedDateTime); + } + + public boolean isAfterDate(ZonedDateTime other) { + return zonedDateTime.truncatedTo(ChronoUnit.DAYS).isAfter(other.truncatedTo(ChronoUnit.DAYS)); + } } diff --git a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DateTimeTypeTest.java b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DateTimeTypeTest.java index 8b240bff5eb..d84fe46f559 100644 --- a/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DateTimeTypeTest.java +++ b/bundles/org.openhab.core/src/test/java/org/openhab/core/library/types/DateTimeTypeTest.java @@ -43,6 +43,7 @@ * @author Erdoan Hadzhiyusein - Added ZonedDateTime tests * @author Laurent Garnier - Enhanced tests * @author Gaël L'hopital - added ability to use second and milliseconds unix time + * @author Gaël L'hopital - added isToday, isTomorrow, isYesterday tests */ @NonNullByDefault public class DateTimeTypeTest { @@ -290,6 +291,46 @@ public void epochTest() { assertThat(epochStandard, is(zdtStandard)); } + @Test + public void relativeTest() { + DateTimeType dt1 = new DateTimeType("2019-06-13T01:10:00+02"); + DateTimeType dt2 = new DateTimeType("2019-06-12T23:00:00Z"); + assertTrue(dt1.isAfter(dt2)); + assertTrue(dt2.isBefore(dt1)); + + assertTrue(dt1.sameDay(dt2)); + assertTrue(new DateTimeType().isToday()); + + DateTimeType now = new DateTimeType(); + DateTimeType tomorrow = new DateTimeType(now.getZonedDateTime().plusDays(1)); + DateTimeType yesterday = new DateTimeType(now.getZonedDateTime().minusDays(1)); + assertTrue(tomorrow.isTomorrow()); + assertTrue(yesterday.isYesterday()); + + DateTimeType dt1ToToday = dt1.toToday(); + assertTrue(dt1ToToday.sameDay(now)); + assertEquals(dt1ToToday.getZonedDateTime().getHour(), dt1.getZonedDateTime().getHour()); + assertEquals(dt1ToToday.getZonedDateTime().getMinute(), dt1.getZonedDateTime().getMinute()); + assertEquals(dt1ToToday.getZonedDateTime().getSecond(), dt1.getZonedDateTime().getSecond()); + assertEquals(dt1ToToday.getZonedDateTime().getNano(), dt1.getZonedDateTime().getNano()); + + DateTimeType dt1ToTomorrow = dt1.toTomorrow(); + assertTrue(dt1ToTomorrow.isAfterDate(now)); + + DateTimeType dt1ToYesterday = dt1.toYesterday(); + assertTrue(dt1ToYesterday.isBeforeDate(now)); + + DateTimeType dt3 = new DateTimeType("2019-06-11T23:10:00Z"); + DateTimeType dt4 = new DateTimeType("2019-06-12T23:00:00Z"); + assertFalse(dt3.sameDay(dt4)); + + assertTrue(dt3.isBeforeDate(dt4)); + assertTrue(dt3.isAfterTime(dt4)); + + assertTrue(dt4.isAfterDate(dt3)); + assertTrue(dt4.isBeforeTime(dt3)); + } + @ParameterizedTest @MethodSource("parameters") public void createDate(ParameterSet parameterSet) {