错误java.time.format.DateTimeParseException:无法解析,在索引10处找到未解析的文本

时间:2016-08-19 07:35:55

标签: date java-8 java-time parse-error localdate

我正在尝试使用LocalDateTime来设置下一个String,但我总是得到de unparsed text found错误:

Error java.time.format.DateTimeParseException: Text '2016-08-18 14:27:15.103+02' could not be parsed, unparsed text found at index 10

这是我的字符串:convertDate:' 2016-08-18 14:27:15.103 + 02 '

我的代码:

public static LocalDate conversorStringToLocalDateTime(String convertDate) throws ParseException {
    LocalDate dateTime =LocalDate.parse(convertDate);
    return dateTime;
}

我猜不是太复杂,买我不能看到错误。字符串中的 +02 可能是原因吗?

2 个答案:

答案 0 :(得分:5)

您的代码正在使用LocalDate,它仅解析日期 - 而不是日期和时间,因此当解析在日期之后找到空格时您会收到错误。

所以你应该使用LocalDateTime,但LocalDateTime.parse(String)要求ISO格式的日期不是你正在使用的格式。

因此,您需要使用DateTimeFormatter来指定输入字符串的格式。类似的东西:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX");
LocalDateTime result = LocalDateTime.parse(convertDate, format);

答案 1 :(得分:5)

TL;博士

OffsetDateTime odt = OffsetDateTime.parse ( "2016-08-18 14:27:15.103+02" , DateTimeFormatter.ofPattern ( "yyyy-MM-dd HH:mm:ss.SSSX" ) ) ;

详细

Answer by greg-449对于问题是正确的(使用仅日期对象作为日期时间值)但不是解决方案。

该答案使用LocalDateTime,不必要地丢弃了有关offset-from-UTC的有价值信息。 LocalDateTime 代表时间轴上的特定时刻,只是根据调整到特定时区的可能时刻的模糊概念。

+02offset-from-UTC,意思是“比UTC提前两小时”。所以在UTC中,这个同步时刻的时间是12小时,比14小时少2小时。此 代表时间轴上的特定时刻。此偏移量是您使用LocalDateTime而不是OffsetDateTime丢弃的有价值信息。

您的字符串格式为SQL格式,接近标准ISO 8601格式。仅使用T替换中间的SPACE。默认情况下,java.time类使用ISO 8601格式,因此无需指定格式化模式。

String input = "2016-08-18 14:27:15.103+02";
String inputModified = input.replace ( " " , "T" );

不幸的是,Java 8在解析缩写为一小时的偏移值或在小时和分钟之间省略冒号的偏移值方面存在错误。已在Java 9中修复。但在Java 8中,我们需要调整输入。

// Workaround for Java 8 where 2-digit offset fails parsing. Fixed in Java 9.
int lengthOfAbbreviatedOffset = 3;
if ( inputModified.indexOf ( "+" ) == ( inputModified.length () - lengthOfAbbreviatedOffset ) ) {
    // If third character from end is a PLUS SIGN, append ':00'.
    inputModified = inputModified + ":00";
}
if ( inputModified.indexOf ( "-" ) == ( inputModified.length () - lengthOfAbbreviatedOffset ) ) {
    // If third character from end is a PLUS SIGN, append ':00'.
    inputModified = inputModified + ":00";
}

现在解析。

OffsetDateTime odt = OffsetDateTime.parse ( inputModified );

转储到控制台。请注意我们如何将+02转换为+02:00

System.out.println ( "input: " + input + " | inputModified: " + inputModified + " | odt: " + odt );
  

输入:2016-08-18 14:27:15.103 + 02 | inputModified:2016-08-18T14:27:15.103 + 02:00 | odt:2016-08-18T14:27:15.103 + 02:00

或者,指定格式设置模式。使用此格式化模式时,偏移解析错误不会发生。

    DateTimeFormatter f = DateTimeFormatter.ofPattern ( "yyyy-MM-dd HH:mm:ss.SSSX" );
    OffsetDateTime odt = OffsetDateTime.parse ( input , f );

数据库

来自Postgres,您应该将值检索为日期时间对象而不是String。

如果您的JDBC驱动程序符合JDBC 4.2,您可以致电ResultSet::getObject以获取InstantOffsetDateTime。如果没有,请调用ResultSet::getTimestamp获取java.sql.Timestamp,然后通过调用Timestamp对象上的toInstant立即转换为java.time。

坚持使用java.time作为您的业务逻辑;简单地使用java.sql类型,仅用于与数据库交换。