【问题标题】:Error java.time.format.DateTimeParseException: could not be parsed, unparsed text found at index 10错误 java.time.format.DateTimeParseException:无法解析,在索引 10 处找到未解析的文本
【发布时间】:2016-08-28 04:36:10
【问题描述】:

我正在尝试使用 LocalDateTime 粘贴下一个字符串,但我总是得到 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 可能是原因吗?

【问题讨论】:

  • 我认为是日期和时间之间的空间。那是空格字符还是不间断空格?如果您的字符串来自某种形式,那可能是不同于空格的字符
  • 来自 Postgre 数据库

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


【解决方案1】:

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。 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 |输入修改:2016-08-18T14:27:15.103+02:00 |时间: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,您应该将值作为日期时间对象而不是字符串来检索。

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

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

【讨论】:

    【解决方案2】:

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

    所以您应该使用LocalDateTime,但LocalDateTime.parse(String) 需要一个不是您使用的格式的 ISO 格式日期。

    因此您需要使用DateTimeFormatter 来指定输入字符串的格式。比如:

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

    【讨论】:

    • 是的!!!那行得通!我之前也尝试过使用 LocalDateTime,但使用了磨损的 DateTimeFormatter。谢谢:)
    猜你喜欢
    • 2020-08-10
    • 2019-07-10
    • 1970-01-01
    • 2020-02-16
    • 1970-01-01
    • 2021-06-01
    • 2016-10-02
    • 2017-12-09
    • 1970-01-01
    相关资源
    最近更新 更多