Jonas Frid
02/03/2022, 8:19 AMjush
02/03/2022, 9:25 AMNicolas Patin
02/03/2022, 9:34 AM/**
* 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:
@Serializable
data class YourDto(
@Serializable(with = InstantWithBaseOffsetSerializer::class)
val date: Instant? = null
)
Jonas Frid
02/03/2022, 9:59 AM