diff --git a/src/main/java/io/leonard/OpeningHoursEvaluator.java b/src/main/java/io/leonard/OpeningHoursEvaluator.java index bf9c3a62d93..046980fb816 100644 --- a/src/main/java/io/leonard/OpeningHoursEvaluator.java +++ b/src/main/java/io/leonard/OpeningHoursEvaluator.java @@ -202,21 +202,33 @@ private static boolean dateMatchesDateRanges(LocalDateTime time, List private static boolean dateMatchesDateRange(LocalDateTime time, DateRange range) { // if the end date is null it means that it's just a single date like in "2020 Aug 11" DateWithOffset startDate = range.getStartDate(); - boolean afterStartDate = - time.getYear() >= startDate.getYear() && - time.getMonth().ordinal() >= startDate.getMonth().ordinal() && - time.getDayOfMonth() >= startDate.getDay(); + boolean afterStartDate = isSameDateOrAfter(time, startDate); + if (range.getEndDate() == null) { return afterStartDate; } DateWithOffset endDate = range.getEndDate(); - boolean beforeEndDate = - time.getYear() <= endDate.getYear() && - time.getMonth().ordinal() <= endDate.getMonth().ordinal() && - time.getDayOfMonth() <= endDate.getDay(); + boolean beforeEndDate = !isSameDateOrAfter(time.minusDays(1), endDate); return afterStartDate && beforeEndDate; } + private static boolean isSameDateOrAfter(LocalDateTime time, DateWithOffset startDate) { + return ( + time.getYear() > startDate.getYear() || + ( + time.getYear() == startDate.getYear() && + startDate.getMonth() != null && + ( + time.getMonth().ordinal() > startDate.getMonth().ordinal() || + ( + time.getMonth().ordinal() == startDate.getMonth().ordinal() && + time.getDayOfMonth() >= startDate.getDay() + ) + ) + ) + ); + } + private static boolean timeMatchesHours(LocalDateTime time, TimeSpan timeSpan) { var minutesAfterMidnight = minutesAfterMidnight(time.toLocalTime()); return timeSpan.getStart() <= minutesAfterMidnight && timeSpan.getEnd() >= minutesAfterMidnight; diff --git a/src/test/java/org/opentripplanner/street/model/OHRulesRestrictionTest.java b/src/test/java/org/opentripplanner/street/model/OHRulesRestrictionTest.java index 294abcb2acb..b1a8216e5cb 100644 --- a/src/test/java/org/opentripplanner/street/model/OHRulesRestrictionTest.java +++ b/src/test/java/org/opentripplanner/street/model/OHRulesRestrictionTest.java @@ -35,7 +35,15 @@ public void testRepeatingTimePeriod() throws OpeningHoursParseException { @ParameterizedTest @ValueSource( strings = { - "mo-su 06:00-23:00", "fri", "none @ sat", "2024 Jul 26", "2024 Jul 25 - 2024 Jul 27", + "mo-su 06:00-23:00", + "fri", + "none @ sat", + "2024 Jul 26", + "2024 Jul 25 - 2024 Jul 27", + "2024 Jul 25 - 2024 Jul 26", + "2024 Jul 26 - 2024 Jul 26", + "2024 Jul 25 - 2025 May 27", + "2024 Jul 25 - 2024 Jul 27", } ) // six numbers // Note: hours only restrictions (e.g. "06:00-23:00") are not yet supported @@ -50,4 +58,19 @@ public void testOHCalendarRestrictionOpen(String condition) throws OpeningHoursP long time = dateTime.getEpochSecond(); assertTrue(tr.active(time)); } + + @ParameterizedTest + @ValueSource(strings = { "2024 Jul 1 - 2099 Dec 31" }) // six numbers + // Note: hours only restrictions (e.g. "06:00-23:00") are not yet supported + public void testOHCalendarRestrictionActive(String condition) throws OpeningHoursParseException { + TimeRestriction tr = OHRulesRestriction.parseFromCondition( + condition, + () -> { + return zoneId; + } + ); + Instant dateTime = Instant.parse("2025-04-01T10:30:00Z"); + long time = dateTime.getEpochSecond(); + assertTrue(tr.active(time)); + } }