MoshiでLocalDateTime型を変換するときのカスタムアダプター

LocalDateTime型のプロパティがあるdata classをJsonに変換しようとしたところエラーがでた。

Platform class java.time.LocalDateTime requires explicit JsonAdapter to be registered

data classとJsonに変換している関数 Jsonに変換している関数はRepositoryに定義している。

data class Hoge {
  val id: Int,
  val hogehoge: String
  val time: LocalDateTime,
}

private fun convertJson(hoge: Hoge): String {
    val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
    val jsonAdapter = moshi.adapter(Hoge::class.java)
    return jsonAdapter.toJson(hoge)
}

結論

LocalDateTime型用のアダプターを実装し、Moshi.Builderに追加する。

Moshiに内蔵されているadapterはプリミティブ型やMapなどでLocalDateTImeは対応していない。

github.com

FromJsonアノテーション、ToJsonアノテーションを使用してCustom Adapterを作る。

// LocalDateTimeAdapter.kt
import com.squareup.moshi.ToJson
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

class LocalDateTimeAdapter {
    @FromJson
    fun fromJson(json: String): LocalDateTime {
        return LocalDateTime.parse(json, DateTimeFormatter.ISO_DATE_TIME)
    }
    
    @ToJson
    fun toJson(value: LocalDateTime): String {
        return value.format(DateTimeFormatter.ISO_DATE_TIME)
    }
}

このLocalDateTimeAdapterMoshi.Builder()に追加することでLocalDateTime型を変換できるようになる。

CustomAdapterはKotlinJsonAdapterFactory()より前に書く必要があるので注意。

private fun convertJson(hoge: Hoge): String {
    val moshi = Moshi.Builder()
        .add(LocalDateTimeBuilder())
        .add(KotlinJsonAdapterFactory())
        .build()
    val jsonAdapter = moshi.adapter(Hoge::class.java)
    return jsonAdapter.toJson(hoge)
}