[alibaba/fastjson]ISO 8601日期在经过fastjson解析时候经常报NumberFormatException

2025-11-12 629 views
3

报错详情如下:

Caused by: java.lang.NumberFormatException: For input string: "3017-08-28T00:00:00+08:00"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.lang.Long.parseLong(Long.java:589)
    at java.lang.Long.parseLong(Long.java:631)
    at com.alibaba.fastjson.serializer.DateCodec.cast(DateCodec.java:202)
    at com.alibaba.fastjson.parser.deserializer.AbstractDateDeserializer.deserialze(AbstractDateDeserializer.java:142)
    at com.alibaba.fastjson.parser.deserializer.AbstractDateDeserializer.deserialze(AbstractDateDeserializer.java:19)
    at com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer.parseField(DefaultFieldDeserializer.java:71)

经过分析之后,发现是JSONScanner类中下面这段代码可能有问题:

static boolean checkDate(char y0, char y1, char y2, char y3, char M0, char M1, int d0, int d1) {
        if (y0 != '1' && y0 != '2') {//备注: 在检验是否是IOS8601日期的时候,y0会判断是否是1或者2,由于我这里不是1、2,所以判定为不是IOS8601日期,所以报错了
            return false;
        }
        if (y1 < '0' || y1 > '9') {
            return false;
        }
        if (y2 < '0' || y2 > '9') {
            return false;
        }
        if (y3 < '0' || y3 > '9') {
            return false;
        }

当时我翻阅wiki发现

ISO 8601 prescribes, as a minimum, a four-digit year [YYYY] to avoid the year 2000 problem. It therefore represents years from 0000 to 9999, year 0000 being equal to 1 BC and all others AD. However, years prior to 1583 are not automatically allowed by the standard. Instead "values in the range [0000] through [1582] shall only be used by mutual agreement of the partners in information interchange. 地址

上面说YYYY取值可以是0000-9999,所以这个判定方法是不是有问题呢?

回答

8

3017这样的日期怎么来的?

2

肯定是测试时的mock数据呗~

9

这个日期是运营人员填写的商品过期时间,这个应该没有限制吧

5

商品过期时间3017年,加这个支持,觉得会容易导致一些数据误判,能业务自行处理么?

8

谢谢,今天忘记回复了,可以使用@JSONField规避这个问题,修复了更好哈