当尝试从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)。
答案 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标准。
java.time 类在解析/生成字符串时默认使用标准格式。因此,无需指定格式设置模式。
LocalDateTime
您的输入字符串缺少指示符time zone或offset-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:
+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
可能代表的日期与输入字符串中的日期不同,可以是输入字符串日期之前或之后的一天。