Skip to content

Fix bug parsing "12AM" as noon instead of midnight #11

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,21 @@ class EnglishDateTimeExtractor internal constructor(
pm = ts.tryOrSkipDateTimeIgnore(true) {
Utils.firstNotNull(
dateTimeExtractor::ampm,
{ DateTimeExtractorUtils.isMomentOfDayPm(momentOfDay()) }
{ momentOfDay()?.let(DateTimeExtractorUtils::isMomentOfDayPm) }
)
}
}

if (pm != null && pm && !DateTimeExtractorUtils.isMomentOfDayPm(time.hour)!!) {
// time must be in the afternoon, but time is not already in the afternoon, correct it
time = time.withHour((time.hour + 12) % DateTimeExtractorUtils.HOURS_IN_DAY)
if (time.hour != 0 && pm != null) {
// AM/PM should not do anything after 0 (e.g. 0pm or 24 in the evening)

if (!pm && time.hour == 12) {
// AM was specified after 12 (e.g. 12AM), so the time is midnight
time = time.withHour(0)
} else if (pm && !DateTimeExtractorUtils.isMomentOfDayPm(time.hour)) {
// time must be in the afternoon, but time is not already, correct it
time = time.withHour((time.hour + 12) % DateTimeExtractorUtils.HOURS_IN_DAY)
}
}
return time
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,18 @@ class ItalianDateTimeExtractor internal constructor(
pm = ts.tryOrSkipDateTimeIgnore(true) {
Utils.firstNotNull(
dateTimeExtractor::ampm,
{ DateTimeExtractorUtils.isMomentOfDayPm(momentOfDay()) }
{ momentOfDay()?.let(DateTimeExtractorUtils::isMomentOfDayPm) }
)
}
}

if (pm != null && pm && !DateTimeExtractorUtils.isMomentOfDayPm(time.hour)!!) {
// time must be in the afternoon, but time is not already in the afternoon, correct it
time = time.withHour((time.hour + 12) % DateTimeExtractorUtils.HOURS_IN_DAY)
if (time.hour != 0 && pm != null) {
// AM/PM should not do anything after 0 (e.g. 0pm or 24 di sera)

if (pm && !DateTimeExtractorUtils.isMomentOfDayPm(time.hour)) {
// time must be in the afternoon, but time is not already, correct it
time = time.withHour((time.hour + 12) % DateTimeExtractorUtils.HOURS_IN_DAY)
}
}
return time
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,7 @@ class DateTimeExtractorUtils(
val MONTHS_IN_YEAR: Long = Month.entries.size.toLong() // 12

@JvmStatic
fun isMomentOfDayPm(momentOfDay: Int?): Boolean? {
if (momentOfDay == null) {
return null
}
fun isMomentOfDayPm(momentOfDay: Int): Boolean {
return momentOfDay >= 12
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,9 @@ public void testTimeWithAmpm() {
assertTimeWithAmpm("18:29:02 and am", LocalTime.of(18, 29, 2), 5);
assertTimeWithAmpm("evening", LocalTime.of(21, 0, 0), 1);
assertTimeWithAmpm("afternoon at four and three and six", LocalTime.of(16, 3, 6), 7);
// this turns out wrong, but it is a corner case
assertTimeWithAmpm("twenty four in the evening", LocalTime.of(12, 0, 0), 5);
// corner cases:
assertTimeWithAmpm("twenty four in the evening", LocalTime.of(0, 0, 0), 5);
assertTimeWithAmpm("12 am", LocalTime.of(0, 0, 0), 2);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,17 @@ public void testTimeNull() {

@Test
public void testTimeWithAmpm() {
assertTimeWithAmpm("11:28.33 pm test", LocalTime.of(23, 28, 33), 5);
assertTimeWithAmpm("mezzogiorno e mezzo dopo pranzo", LocalTime.of(12, 30, 0), 5);
assertTimeWithAmpm("alle due di notte", LocalTime.of(2, 0, 0), 4);
assertTimeWithAmpm("le tre e trentotto di pomeriggio", LocalTime.of(15, 38, 0), 7);
assertTimeWithAmpm("18:29:02 e am", LocalTime.of(18, 29, 2), 5);
assertTimeWithAmpm("sera", LocalTime.of(21, 0, 0), 1);
assertTimeWithAmpm("pomeriggio alle quattro e tre e sei", LocalTime.of(16, 3, 6), 7);
// this turns out wrong, but it is a corner case
assertTimeWithAmpm("le ventiquattro di sera", LocalTime.of(12, 0, 0), 5);
assertTimeWithAmpm("11:28.33 pm test", LocalTime.of(23, 28, 33), 5);
assertTimeWithAmpm("mezzogiorno e mezzo dopo pranzo", LocalTime.of(12, 30, 0), 5);
assertTimeWithAmpm("alle due di notte", LocalTime.of(2, 0, 0), 4);
assertTimeWithAmpm("le tre e trentotto di pomeriggio", LocalTime.of(15, 38, 0), 7);
assertTimeWithAmpm("18:29:02 e am", LocalTime.of(18, 29, 2), 5);
assertTimeWithAmpm("sera", LocalTime.of(21, 0, 0), 1);
assertTimeWithAmpm("pomeriggio alle quattro e tre e sei", LocalTime.of(16, 3, 6), 7);
// corner cases:
assertTimeWithAmpm("le ventiquattro di sera", LocalTime.of(0, 0, 0), 5);
// this is different than in English on purpose
assertTimeWithAmpm("12 am", LocalTime.of(12, 0, 0), 2);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,5 @@ public void testIsMomentOfDayPm() {
assertEquals(Boolean.TRUE, isMomentOfDayPm(12));
assertEquals(Boolean.TRUE, isMomentOfDayPm(18));
assertEquals(Boolean.TRUE, isMomentOfDayPm(24));
//noinspection ConstantConditions
assertNull(isMomentOfDayPm(null));
}
}