A JSON-API-response contains the following properties:
created_at_timestamp: 1565979486,
timezone: "+01:00",
I am using Moshi and ThreeTenBp to parse the time stamps and prepared the following custom adapters:
class ZonedDateTimeAdapter {
@FromJson
fun fromJson(jsonValue: Long?) = jsonValue?.let {
try {
ZonedDateTime.ofInstant(Instant.ofEpochSecond(jsonValue), ZoneOffset.UTC) // <---
} catch (e: DateTimeParseException) {
println(e.message)
null
}
}
}
As you can see the zone offset is hardcoded here.
class ZonedDateTimeJsonAdapter : JsonAdapter<ZonedDateTime>() {
private val delegate = ZonedDateTimeAdapter()
override fun fromJson(reader: JsonReader): ZonedDateTime? {
val jsonValue = reader.nextLong()
return delegate.fromJson(jsonValue)
}
}
...
class ZoneOffsetAdapter {
@FromJson
fun fromJson(jsonValue: String?) = jsonValue?.let {
try {
ZoneOffset.of(jsonValue)
} catch (e: DateTimeException) {
println(e.message)
null
}
}
}
...
class ZoneOffsetJsonAdapter : JsonAdapter<ZoneOffset>() {
private val delegate = ZoneOffsetAdapter()
override fun fromJson(reader: JsonReader): ZoneOffset? {
val jsonValue = reader.nextString()
return delegate.fromJson(jsonValue)
}
}
The adapters are registered with Moshi
as follows:
Moshi.Builder()
.add(ZoneOffset::class.java, ZoneOffsetJsonAdapter())
.add(ZonedDateTime::class.java, ZonedDateTimeJsonAdapter())
.build()
Parsing the individual fields (created_at_timestamp
, timezone
) works fine. I want however get rid of the hardcoded zone offset. How can I configure Moshi to fall back on the timezone
property when parsing the created_at_timestamp
property.
For the created_at_timestamp
field you should use a type that doesn't have a timezone. This is usually Instant
. It identifies a moment in time independent of which timezone it is being interpreted in.
Then in your enclosing type you can define a getter method to combine the instant and zone into one value. The ZonedDateTime.ofInstant
method can do this.