Как одновременно анализировать отметку времени и смещение часового пояса с помощью Moshi?

Ответ JSON-API содержит следующие свойства:

created_at_timestamp: 1565979486,
timezone: "+01:00",

Я использую Moshi и ThreeTenBp для анализа меток времени и подготовил следующие пользовательские адаптеры:

class ZonedDateTimeAdapter {

    @FromJson
    fun fromJson(jsonValue: Long?) = jsonValue?.let {
        try {
            ZonedDateTime.ofInstant(Instant.ofEpochSecond(jsonValue), ZoneOffset.UTC) // <---
        } catch (e: DateTimeParseException) {
            println(e.message)
            null
        }
    }

}

Как видите, смещение зоны здесь жестко задано.

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)
    }

}

Адаптеры регистрируются в Moshi следующим образом:

Moshi.Builder()
    .add(ZoneOffset::class.java, ZoneOffsetJsonAdapter())
    .add(ZonedDateTime::class.java, ZonedDateTimeJsonAdapter())
    .build()

Анализ отдельных полей (created_at_timestamp, timezone) работает нормально. Однако я хочу избавиться от жестко запрограммированного смещения зоны. Как настроить Moshi на использование свойства timezone при разборе свойства created_at_timestamp.

Связанный


person JJD    schedule 08.12.2019    source источник


Ответы (1)


Для поля created_at_timestamp следует использовать тип без часового пояса. Обычно это Instant. Он определяет момент времени независимо от того, в каком часовом поясе он интерпретируется.

Затем в вашем охватывающем типе вы можете определить метод получения, чтобы объединить момент и зону в одно значение. Метод ZonedDateTime.ofInstant может это сделать.

person Jesse Wilson    schedule 08.12.2019
comment
Благодарю вас! Это был идеальный намек. Изменил реализацию по вашей рекомендации, протестировал и обновил ветку. - person JJD; 09.12.2019