Gson用时区反序列化Java.util.Date

时间:2015-12-25 08:19:24

标签: java date timezone gson

我用日期反序列化一个json字符串:

"created_at": "2015-12-24T17:41:54+01:00",

我为gsonBuilder设置了日期格式:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();

反序列化工作没有崩溃;不幸的是,当我打印结果时,它是不正确的:

SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ssZ");
String str = ft.format(response.createdAt);

结果是:

2015-12-24T11:41:54-0500

而不是:

2015-12-24T17:41:54+01:00

2 个答案:

答案 0 :(得分:2)

您尚未将时区设置为仅在日期/时间结束时添加Z,因此它看起来像GMT日期/时间,但这不会更改值。

将时区设置为GMT,这是正确的。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));

答案 1 :(得分:1)

java.time

接受的答案是正确的。但过时了。 java.text.SimpleDateFormat和java.util.Date类已经被添加到Java 8及更高版本的java.time框架过时了。更容易使用,更明智。

ISO 8601

输入字符串的格式符合ISO 8601标准。在解析/生成日期时间值的字符串表示时,java.time类使用ISO 8601作为其默认格式。

String input = "2015-12-24T17:41:54+01:00";

胶印-FROM-UTC

该输入字符串包含offset-from-UTC +01:00,意味着比UTC早一个小时。

ZonedDateTime zdt = ZonedDateTime.parse ( input );
ZoneId z = zdt.getZone ();

偏移与时区

但该偏移是时区。时区是用于处理异常调整(例如夏令时(DST))的偏移规则。因此,您可能希望将您想到的a specific time zone分配给该字符串。也许你打算Amsterdam time

我们可以应用时区来获取另一个ZonedDateTime对象。这种基于旧对象的值创建新对象而不是直接更改旧值的模式称为immutable objects

ZoneId是java.time中的完整时区。它的子类ZoneOffset用于简单的从UTC值偏移而没有调整规则。

ZoneId zoneIdAmsterdam = ZoneId.of ( "Europe/Amsterdam" );
ZonedDateTime zdtAmsterdam = zdt.withZoneSameInstant ( zoneIdAmsterdam );

toString

当您在toString中调用System.out.println时,java.time类使用ISO 8601格式生成日期时间值的String表示。

请注意,除了与UTC的偏移量之外,java.time还通过在方括号中附加指定时区的名称来扩展ISO 8601。例如,[Europe/Amsterdam]

    System.out.println ( "zdt: " + zdt + " at zoneId z: " + z + " adjusted to zoneIdAmsterdam: " + zoneIdAmsterdam + " is zdtAmsterdam: " + zdtAmsterdam );
  

zdt:2015-12-24T17:41:54 + 01:00在zoneId z:+01:00调整为zoneIdAmsterdam:欧洲/阿姆斯特丹是zdtAmsterdam:2015-12-24T17:41:54 + 01:00 [欧洲/阿姆斯特丹]

Instant

通常在我们的业务逻辑和数据存储中,我们严格按UTC工作,仅将时区应用于向用户呈现。为此,传递并存储Instant类的实例。此类表示UTC时间轴上的时刻。

Instant instant = zdt.toInstant();