具有多种格式的 Moshi LocalDateTime 适配器
Moshi LocalDateTime adapter with multiple format
默认情况下,ThreeTenABP.LocalDateTime转换为
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":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,"second":18}}
2018-04-10T03:45:26.009
除了识别 fromJson
中使用的格式外,我很好奇 Moshi 如何在内部为 LocalDateTimetoJson/fromJson 执行 toJson/fromJson
您需要使用 JsonReader.peek()
来确定传入的格式 JSON,然后采取相应的措施。
首先安装一个将LocalDateTime
转换为字符串的适配器。该适配器应使用限定符注释。
@Retention(RetentionPolicy.RUNTIME)
@JsonQualifier
@interface DateString {
}
接下来创建字符串适配器。它应该很简单,可以委托给 Moshi 的 built-in Rfc3339DateJsonAdapter.
public final class LocalDateAsStringAdapter {
@ToJson String toJson(@DateString LocalDateTime localDateTime) {
...
}
@FromJson @DateString LocalDateTime fromJson(String string) {
...
}
}
最后创建一个适配器,委托给 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 允许您为 @ToJson
和 @FromJson
方法声明多个 JsonAdapter
参数,并且这些参数可以被注释。
如果类型相同,它还依赖于此功能的工作方式。在这里,我们通过委托给另一个 JsonAdapter<LocalDateTime>
来创建一个 JsonAdapter<LocalDateTime>
。当类型相同时,Moshi 使用其 nextAdapter()
功能进行组合。
默认情况下,ThreeTenABP.LocalDateTime转换为
{"date":{"day":10,"month":4,"year":2018},"time":{"hour":3,"minute":34,"nano":115000000,"second":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,"second":18}}
2018-04-10T03:45:26.009
除了识别 fromJson
中使用的格式外,我很好奇 Moshi 如何在内部为 LocalDateTimetoJson/fromJson 执行 toJson/fromJson
您需要使用 JsonReader.peek()
来确定传入的格式 JSON,然后采取相应的措施。
首先安装一个将LocalDateTime
转换为字符串的适配器。该适配器应使用限定符注释。
@Retention(RetentionPolicy.RUNTIME)
@JsonQualifier
@interface DateString {
}
接下来创建字符串适配器。它应该很简单,可以委托给 Moshi 的 built-in Rfc3339DateJsonAdapter.
public final class LocalDateAsStringAdapter {
@ToJson String toJson(@DateString LocalDateTime localDateTime) {
...
}
@FromJson @DateString LocalDateTime fromJson(String string) {
...
}
}
最后创建一个适配器,委托给 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 允许您为 @ToJson
和 @FromJson
方法声明多个 JsonAdapter
参数,并且这些参数可以被注释。
如果类型相同,它还依赖于此功能的工作方式。在这里,我们通过委托给另一个 JsonAdapter<LocalDateTime>
来创建一个 JsonAdapter<LocalDateTime>
。当类型相同时,Moshi 使用其 nextAdapter()
功能进行组合。