json dates with the offset format (2022-02-02T08:0...
# multiplatform
j
json dates with the offset format (2022-02-02T080000+00:00) can’t be deserialized to kotlinx.datetime.LocalDateTime. Any suggestions how I can manage this? KMM does not include OffsetDateTime.
j
I think there are some workaround at https://github.com/Kotlin/kotlinx-datetime/issues/139
n
You can declare this serializer:
Copy code
/**
 * kotlinx.DateTime version is currently 0.3.1, and ISO8601 date parsing for
 * dates with time zoned formatted as "+0000" is not supported yet,
 * so we have to use this custom serializer to handle such dates.
 */
object InstantWithBaseOffsetSerializer : KSerializer<Instant> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("InstantWithBaseOffset", PrimitiveKind.STRING)
    override fun serialize(encoder: Encoder, value: Instant) = error("Decoder only")
    override fun deserialize(decoder: Decoder): Instant = Instant.parseWithBasicOffset(decoder.decodeString())
}

// See <https://github.com/Kotlin/kotlinx-datetime/issues/139#issuecomment-976461154> for
// the base implementation.
// A try-catch block has been added to always try to use the library implementation first.
internal fun Instant.Companion.parseWithBasicOffset(string: String): Instant {
    return try {
        parse(string)
    } catch (e: Exception) {
        var lastDigit = string.length
        while (lastDigit > 0 && string[lastDigit - 1].isDigit()) { --lastDigit }
        val digits = string.length - lastDigit // how many digits are there at the end of the string
        if (digits <= 2)
            return parse(string) // no issue in any case
        var newString = string.substring(0, lastDigit + 2)
        lastDigit += 2
        while (lastDigit < string.length) {
            newString += ":" + string.substring(lastDigit, lastDigit + 2)
            lastDigit += 2
        }

        parse(newString)
    }
}
and use it like that:
Copy code
@Serializable
data class YourDto(
    @Serializable(with = InstantWithBaseOffsetSerializer::class)
    val date: Instant? = null
)
j
Thanks! I’ll try it out!
286 Views