首页 > 解决方案 > 使用 BeanIO 解析 RFC3339 日期字符串 'ss.SSSXX'

问题描述

我正在尝试解析这样的字符串日期:2021-03-19T13:08:32.58600在我的模板中使用 BeanIO:

<field name="updatedAt" typeHandler="dateTypeHandler" format="yyyy-MM-dd'T'HH:mm:SSSXX"/>

我得到了Invalid date错误。

我用 SimpleDateFormat 测试了一些案例,例如,如果我做这样的事情: new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(text)它可以工作。

问题出在DateTypeHandlerSupport课堂上,方法 parse 验证长度:

    protected Date parseDate(String text) throws TypeConversionException {
        if ("".equals(text))
            return null;

        ParsePosition pp = new ParsePosition(0);
        Date date = getFormat().parse(text, pp);
        if (pp.getErrorIndex() >= 0 || pp.getIndex() != text.length()) {
            throw new TypeConversionException("Invalid date");
        }
        return date;
    }

有什么方法可以在不创建自己的 DateTypeHandler 的情况下解析字符串?

标签: javadatebean-iorfc3339

解决方案


您的字符串的尾随00不是有效的 UTC 偏移量。我非常确信它从来就不是一个。相反,您的字符串为我们提供了 5 位小数的秒数,并且不包括偏移量。

很抱歉,您无法解析。如果 BeanIO 内部使用SimpleDateFormat(一个臭名昭著的类麻烦制造者,幸好早已过时),那么它就无法2021-03-19T13:08:32.58600正确解析。SimpleDateFormat仅支持秒的小数点后三位,并将解析.58600为 58600 毫秒,即 58.6 秒(这是正确的)。请参阅底部相关问题的链接。

此外,您的字符串不符合 RFC-3339。根据 RFC-3339,时间戳必须包含一个time-offsetwhich 必须是 of "Z" / time-numoffset, where time-numoffsetis ("+" / "-") time-hour ":" time-minute。因此,有效偏移量的示例包括Z+00:00+11:00和。如果您从某个地方收到了作为 RFC-3339 的字符串,那么您似乎需要对发布者进行有关该格式标准的教育。-00:00-11:00

在 Java 中解析字符串很容易。

    String yourString = "2021-03-19T13:08:32.58600";
    LocalDateTime ldt = LocalDateTime.parse(yourString);
    System.out.println(ldt);

输出:

2021-03-19T13:08:32.586

java.time 类将最常见的 ISO 8601 格式变体解析为它们的默认值,也就是说,没有任何格式规范。RFC-3339 基于 ISO 8601 并与之相比进行了简化。由于您的字符串不包含 UTC 偏移量,我将其解析为 a LocalDateTime,该类表示没有时区或 UTC 偏移量的日期和时间。

链接


推荐阅读