Lukasz Kalnik
06/05/2024, 11:49 AM2024-06-04T15:36:13Z
using the following pattern:
val PATTERN = "yyyy-MM-dd'T'HH:mm:ssX"
@OptIn(FormatStringsInDatetimeFormats::class)
val dateTimeFormat = LocalDateTime.Format {
byUnicodePattern(PATTERN)
}
override fun deserialize(decoder: Decoder): LocalDateTime {
return LocalDateTime.parse(decoder.decodeString(), dateTimeFormat)
}
Getting the following error:
java.lang.IllegalArgumentException: A UTC-offset-based directive X was used in a format builder that doesn't support UTC offset components
Lukasz Kalnik
06/05/2024, 11:53 AMLocalDateTimeFormat
doesn't support time zones?Robert Williams
06/05/2024, 12:33 PMLukasz Kalnik
06/05/2024, 12:34 PMRobert Williams
06/05/2024, 12:35 PMLukasz Kalnik
06/05/2024, 12:36 PMInstant.Format
Lukasz Kalnik
06/05/2024, 12:38 PMLocalDateFormat
or LocalDate
. Apparently timezon has to be first separated from the string and parsed separately.
https://github.com/Kotlin/kotlinx-datetime?tab=readme-ov-file#working-with-other-string-formatsSam
06/05/2024, 12:41 PMDateTimeComponents.Format
.Lukasz Kalnik
06/05/2024, 12:45 PMval dateTimeFormat = DateTimeComponents.Formats.ISO_DATE_TIME_OFFSET
nowSam
06/05/2024, 12:46 PMInstant.parse(yourString)
, because ISO format is the default.Lukasz Kalnik
06/05/2024, 12:47 PMInstant
if I want to have a LocalDateTime
?Robert Williams
06/05/2024, 12:50 PMLukasz Kalnik
06/05/2024, 12:52 PMLukasz Kalnik
06/05/2024, 12:53 PMobject DateSerializer : KSerializer<LocalDateTime> {
private val dateTimeFormat = DateTimeComponents.Formats.ISO_DATE_TIME_OFFSET
override val descriptor = PrimitiveSerialDescriptor("kotlinx.datetime.LocalDateTime", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): LocalDateTime {
return dateTimeFormat.parse(decoder.decodeString()).toLocalDateTime()
}
override fun serialize(encoder: Encoder, value: LocalDateTime) {
}
}
Lukasz Kalnik
06/05/2024, 12:53 PMLukasz Kalnik
06/05/2024, 12:54 PM2024-06-04T15:36:13Z
and it gets parsed to 2024-06-04T15:36:13
although I'm in UTC+2Sam
06/05/2024, 12:55 PMInstant.parse
instead of dateTimeFormat.parse
Sam
06/05/2024, 12:55 PMDateTimeComponents
instance, which isn't really intended to be used to store values; just for parsingLukasz Kalnik
06/05/2024, 12:55 PMLukasz Kalnik
06/05/2024, 12:56 PMDateTimeComponents.toLocalDateTime()
convert them to a LocalDateTime
?Lukasz Kalnik
06/05/2024, 12:57 PMLocalDateTime
from deserialize()
Sam
06/05/2024, 1:00 PMTimeZone.currentSystemDefault()
to get your computer's current time zoneLukasz Kalnik
06/05/2024, 1:00 PMDateTimeComponents
timeZoneId
it's null
Lukasz Kalnik
06/05/2024, 1:00 PMLukasz Kalnik
06/05/2024, 1:04 PMDateTimeComponents.toLocalDateTime()
Lukasz Kalnik
06/05/2024, 1:04 PMSam
06/05/2024, 1:04 PMInstant.parse
to get an Instant
instead of a DateTimeComponents
.Lukasz Kalnik
06/05/2024, 1:05 PMInstant.parse()
loses the timezone information from parsed stringSam
06/05/2024, 1:05 PMZonedDateTime
, which doesn't exist in Kotlin unfortunately.Lukasz Kalnik
06/05/2024, 1:06 PMLukasz Kalnik
06/05/2024, 1:07 PMDateTimeComponents
seems to parse timezone information, but it's somehow lostLukasz Kalnik
06/05/2024, 1:07 PMpublic val ISO_DATE_TIME_OFFSET: DateTimeFormat<DateTimeComponents> = Format {
date(ISO_DATE)
alternativeParsing({
char('t')
}) {
char('T')
}
hour()
char(':')
minute()
char(':')
second()
optional {
char('.')
secondFraction(1, 9)
}
alternativeParsing({
offsetHours()
}) {
offset(UtcOffset.Formats.ISO)
}
}
Lukasz Kalnik
06/05/2024, 1:09 PMtimeZoneId
is then null
after parsingSam
06/05/2024, 1:11 PMInstant
isn't "losing" the timezone information, it's just decoding it into an actual moment in time.Robert Williams
06/05/2024, 1:12 PMLukasz Kalnik
06/05/2024, 1:12 PMtoLocalDateTime()
would take implicitly the timezone information from the string and put it into my local time zone.Lukasz Kalnik
06/05/2024, 1:12 PMSam
06/05/2024, 1:13 PMOk, so the Instant is by default in UTC?No, an Instant is not in any time zone at all
Lukasz Kalnik
06/05/2024, 1:13 PMDateTimeComponents
with Instant
Lukasz Kalnik
06/05/2024, 1:16 PMDateTimeComponents.toLocalDateTime()
method when it neither takes into account a timezone from the DateTimeComponents
nor takes a timezone as parameter?Lukasz Kalnik
06/05/2024, 1:17 PMSam
06/05/2024, 1:19 PMDateTimeComponents
isn't for conversion; just for parsing and formatting. So its toLocalDateTime()
function doesn't look at any of its fields besides the date and time of day.Lukasz Kalnik
06/05/2024, 1:19 PMLukasz Kalnik
06/05/2024, 1:20 PMLukasz Kalnik
06/05/2024, 1:20 PMSam
06/05/2024, 1:20 PM.toString()
😉Lukasz Kalnik
06/05/2024, 1:20 PMLukasz Kalnik
06/05/2024, 1:20 PMSam
06/05/2024, 1:22 PMDateTimeComponents
had a null time zone ID after parsing the ISO string. It actually puts that information in the offsetHours
field, since the ISO format contains a numeric offset rather than the ID of a specific timezone.