简体   繁体   English

Gson中的DateFormat模式“yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”

[英]DateFormat pattern “yyyy-MM-dd'T'HH:mm:ss.SSS'Z'” in Gson

I have two field like below ( pay attention that the first field has milliseconds section ): 我有两个字段如下( 注意第一个字段有毫秒部分 ):

{
  "updateTime":"2011-11-02T02:50:12.208Z",
  "deliverTime":"1899-12-31T16:00:00Z"
}

I want to deserialize the Json string to an object with Gson, so I get a Gson instance: 我想用Json将Json字符串反序列化为一个对象,所以我得到一个Gson实例:

GsonBuilder gb = new GsonBuilder();
gb.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
gson = gb.create();

The first field is deserialized to Java date type: 2011-11-02 02:50:12.208 (looks like ignored the time zone section-'Z', that's I expected). 第一个字段被反序列化为Java日期类型: 2011-11-02 02:50:12.208 (看起来像忽略了时区部分-'Z',这是我所期望的)。 However, the second field is deserialized to 1900-01-01 00:00:00 (I live in China, +8 GMT here), it seems that the time zone section-'Z' plays a part in deserialization. 但是,第二个字段被反序列化为1900-01-01 00:00:00 (我住在中国,这里是+ 8 GMT),似乎时区部分-'Z'在反序列化中起作用。

Why the second field uses time zone section? 为什么第二个字段使用时区部分? It's not what I expected. 这不是我的预期。

Quick answer 快速回答

First string is correctly parsed using your date format and your local time zone, second one does not respect it, so will be parsed by a default SimpleDateFormat object that has not milliseconds ("yyyy-MM-dd'T'HH:mm:ss'Z' is the parsing format) and uses UTC timezone giving you a "shift" in time part. 使用您的日期格式和您的本地时区正确解析第一个字符串,第二个字符串不尊重它,因此将由没有毫秒的默认SimpleDateFormat对象解析(“yyyy-MM-dd'T'HH:mm:ss 'Z'是解析格式)并使用UTC时区为您提供时间部分的“转换”。

Full answer 完整答案

To fully respond to your question you need to dive into Gson source code. 要完全回答您的问题,您需要深入了解Gson源代码。 More in particular you have to look at code of DefaultDateTypeAdapter that is used to parse dates. 更具体地说,您必须查看用于解析日期的DefaultDateTypeAdapter代码。 You can find all this code at link , but for quick reference I will copy here most relevant parts. 您可以在链接中找到所有这些代码,但为了快速参考,我将在此处复制最相关的部分。

When you call this in the builder: 在构建器中调用它时:

gb.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

you are initializing a DefaultDateTypeAdapter in this way: 您正在以这种方式初始化DefaultDateTypeAdapter:

DefaultDateTypeAdapter(DateFormat enUsFormat, DateFormat localFormat) {
   this.enUsFormat = enUsFormat;
   this.localFormat = localFormat;
   this.iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
   this.iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
}

where: 哪里:

  1. enUsFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") and enUsFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
  2. localFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US)

since the string you have passed in the builder. 自从你在构建器中传递的字符串。

Pay attention that Locale.US is not a timezone and that iso8601Format is the same as enUsFormat without milliseconds but with UTC timezone. 要注意的是Locale.US不是一个时区和iso8601Format相同enUsFormat没有毫秒但UTC时区。

Parsing happens into deserializeToDate method: 解析发生在deserializeToDate方法中:

 private Date deserializeToDate(JsonElement json) {
    synchronized (localFormat) {
      try {
        return localFormat.parse(json.getAsString());
      } catch (ParseException ignored) {
      }
      try {
        return enUsFormat.parse(json.getAsString());
      } catch (ParseException ignored) {
      }
      try {
        return iso8601Format.parse(json.getAsString());
      } catch (ParseException e) {
        throw new JsonSyntaxException(json.getAsString(), e);
      }
    }
  }

where all of three date formats are used in a waterfall approach. 其中所有三种日期格式都用于瀑布式方法。

First Json string: "2011-11-02T02:50:12.208Z". 第一个Json字符串:“2011-11-02T02:50:12.208Z”。 It's parsed immediately by localFormat since has milliseconds and gives you the result you expect using your timezone. 它由localFormat立即解析,因为它有毫秒,并为您提供您期望使用时区的结果。

Second Json string: "1899-12-31T16:00:00Z". 第二个Json字符串:“1899-12-31T16:00:00Z”。 It won't be parsed by localFormat since has not milliseconds, so second chance is enUsFormat that is the same pattern , except for the locale. 它不会被localFormat解析,因为它没有毫秒,所以第二次机会是enUsFormat,它是相同的模式 ,除了语言环境。 So it will fail at the same way. 所以它会以同样的方式失败。

Last chance to parse: iso8601Format , it will, it has no milliseconds, BUT , for construction, it as also a UTC time zone, so it will parse date as UTC while the others parsed using your timezone. 最后解析的机会: iso8601Format ,它将没有毫秒, 但是 ,对于构造,它也是一个UTC时区,因此它将解析日期为UTC,而其他人使用您的时区解析。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Json反序列化“ 2017-09-11 14:28:42”失败,原因是“它似乎适合格式为“ yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”” - Json Deserialization of “2017-09-11 14:28:42” fails with 'while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSS'Z''' 从“yyyy-MM-dd hh:mm:ss.SSS”解析日期和时间 -------> android中的“hh:mm aa” - Parsing Date and time from "yyyy-MM-dd hh:mm:ss.SSS" -------> "hh:mm aa" in android 以 yyyy-MM-dd HH:mm:ss.SSS 格式从当前 dateTime 获取 1 年前的 dateTime - Get 1 year back dateTime from current dateTime in yyyy-MM-dd HH:mm:ss.SSS format XMLGregorianCalendar日期格式'dd / MM / yyyy HH:mm:ss.SSS' - XMLGregorianCalendar date format 'dd/MM/yyyy HH:mm:ss.SSS' @DateTimeFormat(pattern = “yyyy-MM-dd hh:mm:ss”) 不工作 - @DateTimeFormat(pattern = “yyyy-MM-dd hh:mm:ss”) is Not Working 模式“YYYY-MM-dd HH:mm:ss Z”导致解析异常,其中Jodatime没有 - Pattern “YYYY-MM-dd HH:mm:ss Z” causes parsing exception where Jodatime did not 如何比较 java 格式“EEE MMM dd HH:mm:ss zzz yyyy”和“yyyy-MM-dd hh:mm:sss”的日期时间? - How to compare the datetime of format "EEE MMM dd HH:mm:ss zzz yyyy" and "yyyy-MM-dd hh:mm:sss" in java? yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z' 格式 - yyyy-MM-dd'T'HH:mm:ss.SSSSSSS'Z' format 将MYSQL日期时间值转换为UTC时区格式yyyy-MM-dd'T'HH:mm:ss'Z' - convert MYSQL datetime value to UTC Timezone format yyyy-MM-dd'T'HH:mm:ss'Z' Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") 将时区作为 IST - Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM