无法将字符串转换为本地日期

时间:2019-11-11 19:16:38

标签: java

当尝试从String转换为Local Date时,发生错误并且无法解析日期

我正在尝试将字符串格式(例如:2019-11-11T19:12:59.598)的日期转换为本地日期(例如:2019-11-11)。

String dateInString = "2019-11-11T19:12:59.598";

public LocalDateTime DateToYear(String dateInString) {

    Instant instant = Instant.parse(dateInString);

    System.out.println("Instant : " + instant);

    //get date time only
    LocalDateTime result = LocalDateTime.ofInstant(instant, ZoneId.of(ZoneOffset.UTC.getId()));

    //get localdate
    System.out.println("LocalDate : " + result.toLocalDate());

    return result;


}

我的测试方法之一就是调用此方法DateToYear(String dateInString)。

2 个答案:

答案 0 :(得分:2)

如果您将Z放在字符串末尾,它将进行解析。参见DateTimeFormatter.ISO_INSTANT

jshell> Instant.parse("2019-11-11T19:12:59.598")
|  java.time.format.DateTimeParseException thrown: Text '2019-11-11T19:12:59.598' could not be parsed at index 23
|        at DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:2046)
|        at DateTimeFormatter.parse (DateTimeFormatter.java:1948)
|        at Instant.parse (Instant.java:395)
|        at (#10:1)

jshell> Instant.parse("2019-11-11T19:12:59.598Z")
    ==> 2019-11-11T19:12:59.598Z

答案 1 :(得分:2)

ISO 8601

您的输入字符串符合文本日期时间值的ISO 8601标准。

java.time 类在解析/生成字符串时默认使用标准格式。因此,无需指定格式设置模式。

LocalDateTime

您的输入字符串缺少指示符time zoneoffset-from-UTC

所以我们必须解析为LocalDateTime

String dateInString = "2019-11-11T19:12:59.598";
LocalDateTime ldt = LocalDateTime.parse( input ) ;

不要紧

您的输入字符串不是 not 代表时刻,还是 not 在时间轴上的一点。在没有时区或偏移量的情况下,我们不知道您是要在今年11月11日在日本东京,还是在突尼斯突尼斯,还是在托莱多俄亥俄,在今年7月7日下午。这些都是不同的时刻,发生的时间比彼此早/晚几个小时。我们所知道的是,该字符串表示该日期某处的晚上7点,但我们不知道该在哪里,因此我们不知道确切的时间。

要简单地从LocalDateTime中提取仅日期部分,请调用toLocalDate

LocalDate ld = ldt.toLocalDate() ;

由于您输入的时间不是片刻,因此您的行:

Instant instant = Instant.parse(dateInString);

...毫无意义。 Instant代表UTC的时刻,即时间轴上的特定点。但是您的字符串不一定要用于UTC。我们只是不知道偏移量/区域是什么。我们不能仅仅通过查看字符串就知道这一点。

如果您恰好确定输入字符串适用于UTC:

  • 教育发布有关区域/偏移量重要性的数据的人员。如果它们表示UTC,则应在其后附加+00:00或缩写Z(读作“ Zulu”)。
  • 应用常量ZoneOffset.UTC得到一个OffsetDateTime,该ZonedDateTime代表在特定于UTC的偏移量中看到的时刻。

代码:

OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;  // Making a moment of ambiguous input. Do this only if you are *certain* of the zone/offset intended by the publisher of this data input.

获取在该偏移量中看到的那一刻的日期。

LocalDate localDate = odt.toLocalDate() ;

如果可以肯定地确定输入字符串是针对特定时区的,请应用ZoneId以获取{{3}}对象。然后提取LocalDate

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;
LocalDate localDate = zdt.toLocalDate() ;

请记住,在任何给定时刻,日期都会随时区在全球范围内变化。因此,这里的LocalDate可能代表的日期与输入字符串中的日期不同,可以是输入字符串日期之前或之后的一天。