kotlin - 具有多种格式的 Moshi LocalDateTime 适配器

标签 kotlin java-time moshi

默认情况下,ThreeTenABP.LocalDateTime 被转换为

{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano ":115000000,"秒":18}}

我可以编写一个适配器来支持 ISO 日期字符串 2018-04-10T03:45:26.009

class LocalDateTimeAdapter {
    @ToJson
    fun toJson(value: LocalDateTime): String {
        return FORMATTER.format(value)
    }

    @FromJson
    fun fromJson(value: String): LocalDateTime {
        return FORMATTER.parse(value, LocalDateTime.FROM)
    }

    companion object {
        private val FORMATTER = DateTimeFormatter.ISO_LOCAL_DATE_TIME
    }
}

如何编写一个同时支持两种格式的适配器(fromJson)

  • {"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano ":115000000,"秒":18}}
  • 2018-04-10T03:45:26.009

除了识别 fromJson 中使用的格式之外,我很好奇 Moshi 在内部如何为 LocalDateTime 执行 toJson/fromJson

最佳答案

您需要使用 JsonReader.peek()确定传入 JSON 的格式,然后采取相应措施。

首先安装一个可以转换 LocalDateTime 的适配器到一个字符串。该适配器应使用限定符注释。

@Retention(RetentionPolicy.RUNTIME)
@JsonQualifier
@interface DateString {
}

接下来创建字符串适配器。它应该很简单,并且可以委托(delegate)给 Moshi 的内置 Rfc3339DateJsonAdapter。

public final class LocalDateAsStringAdapter {
  @ToJson String toJson(@DateString LocalDateTime localDateTime) {
    ...
  }

  @FromJson @DateString LocalDateTime fromJson(String string) {
    ...
  }
}

最后创建一个适配器,将其委托(delegate)给 Moshi 的内置适配器(将使用 {...})或您的字符串适配器。这个比较喜欢字符串格式,但是你可以做你喜欢的。

public final class MultipleFormatsDateAdapter {
  @ToJson void toJson(JsonWriter writer, LocalDateTime value,
      @DateString JsonAdapter<LocalDateTime> stringAdapter) throws IOException {
    stringAdapter.toJson(writer, value);
  }

  @FromJson LocalDateTime fromJson(JsonReader reader, @DateString JsonAdapter<LocalDateTime> stringAdapter,
      JsonAdapter<LocalDateTime> defaultAdapter) throws IOException {
    if (reader.peek() == JsonReader.Token.STRING) {
      return stringAdapter.fromJson(reader);
    } else {
      return defaultAdapter.fromJson(reader);
    }
  }
}

这是可行的,因为 Moshi 允许您声明多个 JsonAdapter @ToJson 的参数和 @FromJson方法,并且这些参数可以被注释。

如果类型相同,它还依赖于此功能的工作方式。在这里,我们正在制作 JsonAdapter<LocalDateTime>通过委托(delegate)给另一个 JsonAdapter<LocalDateTime> .当类型相同时,Moshi 使用其 nextAdapter()作曲的特征。

关于kotlin - 具有多种格式的 Moshi LocalDateTime 适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49750743/

相关文章:

spring-boot - 将测试容器与另一个数据库驱动程序一起使用

java - 检查给定格式字符串可用于解析的 Temporal 类型

android - 无法使用 Retrofit 2.6.1 成功发送 POST 请求 - JSON 转换器的问题

java - 当 API 通过 JSON 返回 null 值时,使用 Moshi 时有什么方法可以返回 Kotlin 数据类中的默认值

android - Android Jetpack 是否需要使用 Kotlin 语言?

android - Android Studio 中 Android 应用的 Google Play 许可

android - 如何结合 livedata 和 kotlin flow

Java 最快的 OffsetDateTime 解析器

java - Java中是否有任何一致的(单调的)时钟实现?

json - (Kotlin 中的 Moshi)@Json 与 @field :Json