gpt4 book ai didi

java - 为什么我的 DateTime 反序列化会截断 DateTime 分钟/秒/毫秒?

转载 作者:行者123 更新时间:2023-11-30 08:48:53 24 4
gpt4 key购买 nike

我有一个反序列化 JSON 元素的类。

public class DateTimeConverter implements JsonSerializer<DateTime>, JsonDeserializer<DateTime>
{
private static final DateTimeFormatter DATE_FORMAT = ISODateTimeFormat.dateHourMinuteSecondMillis();
@Override
public JsonElement serialize(DateTime src, Type typeOfSrc, JsonSerializationContext context)
{
final DateTimeFormatter fmt = ISODateTimeFormat.dateHourMinuteSecondMillis();
return new JsonPrimitive(fmt.print(src));
}


@Override
public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException
{
final String dateAsString = json.getAsString();
System.out.println(dateAsString);
if (json.isJsonNull() || dateAsString.length()==0)
{
return null;
}
else
{
return DATE_FORMAT.parseDateTime(json.getAsString());
}
}
}

但是,当我输入时,我的反序列化方法:

2015-07-29T11:00:00.000Z

我收到:

2015-07-29T11

来自 System.out.println(dateAsString); 为什么它会截断我的输入?

我认为我的问题出在我的测试类中:

我构造了一个 DateTime 对象以与 Google 的 Gson 一起使用。但是,我认为 DateTimeType 的默认构造函数不支持分钟/秒/毫秒。有没有一种方法可以扩展 DateTimeType 以支持它?

这是我的测试类:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

import org.joda.time.DateTime;
import org.junit.Test;

import java.lang.reflect.Type;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
/**
* Tests {@link DateTimeConverter}.
*/
public class DateTimeConverterTest {
String testTime = "2015-07-29T11:00:00.001Z";

@Test
public void testDateTimeConverter() throws Exception {
final Gson gson = initCustomGSON();
Type DateTimeType = new TypeToken<DateTime>() {
}.getType();

System.out.println(testTime);
DateTimeConverter timeConverter = new DateTimeConverter();
DateTime m = (gson.fromJson(testTime, DateTimeType));

assertThat("11", is(m.hourOfDay().getAsText()));
}

public Gson initCustomGSON() {
final GsonBuilder builder = new GsonBuilder();
JodaTimeConverters converter = new JodaTimeConverters();
converter.registerAll(builder);
return builder.create();
}

}

最佳答案

这段代码有一些问题。

  1. 您的第一个问题是 : 是 Json 中的运算符。您正在解释一个未转义的 String 其中包含一个 :,因此 Gson 将其解释为 key : 值(value)。您的测试字符串需要用引号将整个文本日期括起来,以防止发生这种情况,例如

    String testTime = "\"2015-07-29T11:00:00.001Z\"";
  2. 您使用的是 ISODateTimeFormat.dateHourMinuteSecondMillis()在你的代码中。但是,它的格式模式是 yyyy-MM-dd'T'HH:mm:ss.SSS,如您所见,它不包括时区。你想使用 ISODateTimeFormat.dateTime() ,其模式为 yyyy-MM-dd'T'HH:mm:ss.SSSZZ,它确实有时区。

    private static final DateTimeFormatter DATE_FORMAT = ISODateTimeFormat.dateTime();
  3. 完成这两项更改后,DateTime 对象最终正确创建...但它将在您的本地时区创建,而不是UTC(它将正确调整您所在区域的时间。您可以通过以下方式轻松地将其切换回 UTC:

    DateTime m = ((DateTime) (gson.fromJson(testTime, DateTimeType))).withZone(DateTimeZone.UTC);

完成这三项更改后,您的测试就会通过。 但是:我强烈建议不要使用 JsonSerializerJsonDeserializer,它们已被弃用,取而代之的是 TypeAdapter ,其流式 API 为 significantly more performant:

New applications should prefer TypeAdapter, whose streaming API is more efficient than this interface's tree API.

我知道用户指南提供了如何使用 JsonSerializer/JsonDeserializer API 执行此操作的代码,但这只是因为他们尚未对其进行更新。

它会像这样:

public class DateTimeAdapter extends TypeAdapter<DateTime> {
private static final DateTimeFormatter FORMAT = ISODateTimeFormat.dateTime();

public DateTime read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
String dateString = reader.nextString();
if(dateString.length() == 0) return null;
return FORMAT.parseDateTime(dateString);
}

public void write(JsonWriter writer, DateTime value) throws IOException {
if (value == null) {
writer.nullValue();
return;
}
writer.value(FORMAT.print(value));
}
}

关于java - 为什么我的 DateTime 反序列化会截断 DateTime 分钟/秒/毫秒?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31710000/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com