用beanio解析rfc3339日期字符串“ss.sssxx”

soat7uwm  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(383)

我试图解析一个字符串日期,如下所示: 2021-03-19T13:08:32.58600 我的模板中有beanio: <field name="updatedAt" typeHandler="dateTypeHandler" format="yyyy-MM-dd'T'HH:mm:SSSXX"/> 而我正在 Invalid date 错误。
我用SimpleDataFormat测试了一些案例,例如,如果我这样做: new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(text) 它起作用了。
问题出在 DateTypeHandlerSupport 类,方法解析验证长度:

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的情况下解析字符串?

rvpgvaaj

rvpgvaaj1#

尾随 00 字符串的偏移量不是有效的utc偏移量。我很确信这不是命中注定的。相反,您的字符串为我们提供了5位小数的秒数,并且不包括偏移量。
很抱歉,你无法解析。如果beanio内部使用 SimpleDateFormat (一个臭名昭著的麻烦制造者的类,幸运的是早已过时),那么就没有办法解析 2021-03-19T13:08:32.58600 正确地。 SimpleDateFormat 只支持秒小数的三位小数,将解析 .58600 58600毫秒,也就是58.6秒(没错)。请参阅底部相关问题的链接。
您的字符串也不符合rfc-3339。根据rfc-3339,时间戳必须包括 time-offset 其中一个必须是 "Z" / time-numoffset ,在哪里 time-numoffset("+" / "-") time-hour ":" time-minute . 因此,有效补偿的例子包括 Z , +00:00 , +11:00 , -00:00 以及 -11:00 . 如果您从某处收到了rfc-3339格式的字符串,那么您似乎需要向发布者介绍该格式标准。
用java解析字符串很容易。

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

输出:
2021-03-19t13:08:32.586
time的类将iso8601格式的最常见变体解析为它们的默认值,也就是说,没有任何格式规范。rfc-3339基于iso 8601,与之相比简化了。因为您的字符串不包含utc偏移量,所以我将其解析为 LocalDateTime ,它是不带时区或utc偏移的日期和时间的类。

链接

oracle教程:date time解释如何使用java.time。
相关问题:
使用SimpleDataFormat java[duplicate]解析日期。
yyyy-mm-dd't'hh:mm:ss.sss'z'格式。
征求意见:3339:互联网上的日期和时间:时间戳。

evrscar2

evrscar22#

我知道当前版本(2.1)不支持新的 java.time 课程开箱即用,但它将在新的beanio项目中得到新生。
在我们等待新版本支持 java.time 开箱即用,您可以通过创建自己的 org.beanio.types.TypeHandler 实施,很可能是通过实施 org.beanio.types.ConfigurableTypeHandler . 您可以查看新的temporalaccessortypehandler实现,并使用它暂时运行自己的实现,直到您可以升级到最新版本。这个讨论还展示了如何使用和配置这个类型处理程序。
我不打算复制密码 TemporalAccessorTypeHandler 但您可以这样配置:

// declare/register your new type handler
<typeHandler name="javaTimeTypeHandler" 
    class="path.to.your.implementation.TemporalAccessorTypeHandler" />

// now use it in your fields
<field name="updatedAt" typeHandler="javaTimeTypeHandler" 
    format="yyyy-MM-dd'T'HH:mm:SSSXX"/>

相关问题