I have a form where user can input date and time from keypad and LocalDateTime accepts input when time part of input is 24:00, converting it to next day.
My code
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
val INPUT_DATETIME_PATTERN = "yyyyMMddHHmm"
val formatter = DateTimeFormatter.ofPattern(INPUT_DATETIME_PATTERN)
val datetime = "202308102400"
val localdatetime = LocalDateTime.parse(datetime, formatter)
println(datetime)
println(localdatetime.format(formatter))
Expected result:
LocalDateTime.parse throws an exception.
According to documentation, HH stands for hour-of-day (0-23), so 2400 is invalid. Exception is also thrown for input string 202308102401.
Actual result:
202308110000 is printed. Checked in a scratch in Android Studio and in Kotlin playground (link)
Turns out it is my fault for not reading documentation with enough attention... Thanks Marco F. for pointing me at what I missed.
DateTimeResolver
is created with ResolverStyle.SMART
by default which performs sensible default for each field, e.g. interpreting 24:00 as "first moment of next day" or allows month-of-day values up to 31, silently converting to actual valid day values.
Correct code to get the expected behavior:
val INPUT_DATETIME_PATTERN = "uuuuMMddHHmm"
val formatter = DateTimeFormatter
.ofPattern(INPUT_DATETIME_PATTERN)
.withResolverStyle(ResolverStyle.STRICT)
val datetime = "202308102400"
val localdatetime = LocalDateTime.parse(datetime, formatter)
println(datetime)
println(localdatetime.format(formatter))
Note also that year specifier is changed from yyyy (year of era) to uuuu (year), because strict resolver requires an era to go with YearOfEra (source).