【问题标题】:ISO 8601 with milliseconds and RetrofitISO 8601 与毫秒和改造
【发布时间】:2015-08-29 11:35:21
【问题描述】:

在使用改造并尝试读取这样的日期时,我无法正确设置日期格式:

2015-08-29T11:22:09.815479Z

我设置的GSON 转换器是这样的:

GsonConverter gsonConverter = new GsonConverter(
     new GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSz")
            .create()
);

有什么线索可以说明问题吗?

【问题讨论】:

  • 使用 Java 8 及更高版本中内置的 java.time framework 中的类。它们的分辨率为纳秒,最多可显示九位小数秒。

标签: java android date gson iso8601


【解决方案1】:

Java Date 具有毫秒精度,所以我一直在创建 Gson 对象,如下所示:

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

当然,在这种情况下,无论您输入SSS 还是SSSSSS,微秒都会被截断。还假设转换后的字符串的最后一个字符始终是Z

为了解释为什么您的模式不起作用,您使用了 z(小写 z),根据文档,它代表 General Timezone(例如,Pacific Standard Time; PST; GMT-08:00)。此外,如果您要使用 Z(大写 Z),它也将不起作用,因为它代表 RFC 822 time zone(例如,-0800)。

在另一种情况下,您可以使用时区偏移(例如,-08-0800-08:00)而不是 Z,您可以使用 XXX 或 @987654347 @ 代表ISO 8610 time zone。但这需要 Java 7 或 8(我认为 Android 目前不兼容 Java 8)。


另一种方法是编写自己的GsonSerializer and Deserializer;虽然我没试过。

java.sql.Timestamp 类也值得一看,Gson 也支持它,并且具有更细粒度的精度(纳秒),但它也是我没有探索过的一个选项。

【讨论】:

  • Java 8 及更高版本中内置的大部分 java.time 功能在ThreeTen-Backport 中向后移植到Java 6 和7,并进一步适应ThreeTenABP 中的Android(参见How to use… )。
  • 这真的兼容 ISO 8601 吗?我从未在官方规范中见过millis。这看起来像是标准格式的扩展。
  • @ChristopheRoussy 虽然我没有直接阅读 ISO 8601 规范,因为它受版权保护且价格昂贵,但根据the Wikipedia page小数点的小数位数没有限制分数。但是,小数位数需要通信双方同意。java.time中,Instant等各种类解析为纳秒(九位小数) )。
  • 我认为您的格式化模式是通过用单引号括起来来忽略Z。这意味着您忽略了关键信息:与 UTC 或时区的偏移量。可能有不好的影响,虽然我不知道GsonBuilder的具体影响是什么。
【解决方案2】:

Java 8 Instant 类可用于轻松解析ISO-8601 时间戳,无需显式设置格式字符串,例如:

String input = "2018-11-07T00:25:00.073876Z";
Instant instant = Instant.parse(input);

【讨论】:

    猜你喜欢
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2016-03-07
    相关资源
    最近更新 更多