为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Java 时间库将 ISO 兼容字符串解析为日期

如何使用 Java 时间库将 ISO 兼容字符串解析为日期

梵蒂冈之花 2022-09-22 10:29:04

我有各种格式的时间戳,例如:


2018-07-21T00:50:39

2017-11-20T23:18:27.529Z

我需要将它们解析为java.util.Date,并尝试了以下方法,它们都适用于第一种格式,但第二种格式失败。


以下是我尝试过的方法,它是错误的:


1.


private Date try3(String dateString) {

        return Date.from(Instant.parse(dateString).atZone(ZoneId.of("UTC")).toInstant());

    }

它在第一种格式时失败,错误:


java.time.format.DateTimeParseException: Text '2017-11-20T23:18:28' could not be parsed at index 19

2.


private Date try2(String dateString) {

    return Date.from(LocalDateTime.parse(dateString).atZone(ZoneId.of("UTC")).toInstant());

}

对于第二种格式,此方法会引发错误:


java.time.format.DateTimeParseException: Text '2017-11-20T23:18:27.529Z' could not be parsed, unparsed text found at index 23

3:


private Date try1(String dateString) {

    return Date.from(ZonedDateTime.parse(dateString,

                    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").withZone(ZoneId.of("UTC"))).toInstant());


}

对于第二种格式,上述方法引发错误:


java.time.format.DateTimeParseException: Text '2017-11-20T23:18:27.529Z' could not be parsed, unparsed text found at index 19

我最终得到了乔达图书馆:


private Date try4(String dateString) {

        return new DateTime(dateString).withZone(DateTimeZone.UTC).toDate();

    }

但是真的有没有办法在Java时间库中做到这一点?


查看完整描述

2 回答

?
摇曳的蔷薇

TA贡献1438条经验 获得超7个赞

你总是想得到同样的类型,我似乎明白,如果字符串中没有偏移量,你需要UTC(重要的是要清楚这一点)。我建议指定一个具有可选UTC偏移量和默认值UTC(零偏移量)的格式化程序,以防字符串中没有任何偏移量:

 DateTimeFormatter formatter = new DateTimeFormatterBuilder()

            .append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)

            .appendPattern("[X]")

            .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)

            .toFormatter();


    String withoutZ = "2018-07-21T00:50:39";

    Instant anInstant = formatter.parse(withoutZ, Instant::from);

    System.out.println(anInstant);


    String withZ = "2017-11-20T23:18:27.529Z";

    Instant anotherInstant = formatter.parse(withZ, Instant::from);

    System.out.println(anotherInstant);

输出:


2018-07-21T00:50:39Z

2017-11-20T23:18:27.529Z

格式模式字符串中的方括号表示偏移量 X 是可选的。秒上小数点的存在与否由 处理。[X]ISO_LOCAL_DATE_TIME

我希望您知道该类设计不佳且已经过时,因此通常您不应该想要一个,并且您只要求一个,因为您不可避免地需要一个用于传统API的专用API,而您现在无法更改。在这种情况下,请从您的问题中进行最终转换。DateInstant

通常用于可变日期/时间格式的技术包括:

  1. 依次尝试许多已知格式。

  2. 在确定要使用的格式之前,请先了解一下字符串。在你的情况下,你可能已经分支了,正如巴西尔·布尔克的答案中已经建议的那样。.endsWith("Z")

  3. 格式模式中的可选部件。

  4. DateTimeFormatterBuilder.parseDefaulting()用于已分析字符串中可能不存在的部分。

  5. DateTimeFormatter.parseBest().

如您所见,我正在使用项目3。和 4.这里。


查看完整回答
反对 回复 2022-09-22
?
侃侃尔雅

TA贡献1479条经验 获得超1个赞

时间

这已经被覆盖了无数次。因此,请搜索堆栈溢出以获取更多信息。

切勿使用 或 。仅使用时间。同样,乔达时间也被java.time所取代(两者都由同一个人斯蒂芬科尔伯恩领导)。DateCalendar

两个字符串输入均采用标准 ISO 8601 格式。默认情况下,java.time 类在解析/生成字符串时使用这些格式。

第一个缺少与 UTC 或时区的偏移量指示器,因此它不表示某个时刻。

LocalDateTime.parse( "2018-07-21T00:50:39" )

第二个意思是UTC,发音为“祖鲁”。Z

Instant.parse( "2017-11-20T23:18:27.529Z" )

若要在一种方法中处理这两种格式,请相应地搜索 输入字符串中是否存在 和 分支。此外,陷阱用于异常,以防您收到意外输入。Z

如果必须有一个对象,请参阅该类 JavaDoc 以获取新方法 & 在转换为 java.time 类的旧类上。正如我所说,所有这些都已经被涵盖了很多很多次,所以请搜索更多信息。java.util.Datefromto…


查看完整回答
反对 回复 2022-09-22

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信