fastJSON存储LocalDateTime,引起的格式化异常

        在java开发环境中, 事件过程: LocalDateTime直接作为k-v对的value存储到JSONObject对象,然后直接toJSONString入库处理了,当在别的地方直接引用k,取出对应的value,转为LocalDateTime时候出现了格式异常,大体的demo代码是这样的     

LocalDateTime myDateTime =  LocalDateTime.of(LocalDateTime.now().getYear(), 
                LocalDateTime.now().getMonth(), LocalDateTime.now().getDayOfMonth(), 16, 30, 00); 

       JSONObject josn = new JSONObject();

       josn.put("K", myDateTime);

      //入库处理

      LocalDateTime referenceDatetime = LocalDateTime.parse(json.getString("K"), DateTimeFormatter.
            ofPattern("yyyy-MM-dd HH:mm:ss"));

 

代码逻辑跑了很长一段没有出现任何异常,在fastJSON的jar版本升级后,出现了异常,为啥会这样呢?

再看一下fastJSON  -> toJSONString 实现 v1.2.45   和 v1.2.49

toJSONString -> JSONSerializer -> MapSerializer ->Jdk8DateCodec::write 关注一下源码,容易理解 v1.2.45

public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
                      int features) throws IOException {
        SerializeWriter out = serializer.out;
        if (object == null) {
            out.writeNull();
        } else {
            if (fieldType == null) {
                fieldType = object.getClass();
            }

            if (fieldType == LocalDateTime.class) {
                final int mask = SerializerFeature.UseISO8601DateFormat.getMask();
                LocalDateTime dateTime = (LocalDateTime) object;
                String format = serializer.getDateFormatPattern();

                if (format == null && (features & mask) != 0 || serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) {
                    format = formatter_iso8601_pattern;
                }
                //这是v1.2.45版本的逻辑,问题出在这里dateTime.getNano()=0
                if (dateTime.getNano() == 0 || format != null) {

                    if (format == null) {
                        format = JSON.DEFFAULT_DATE_FORMAT;
                    }
                    write(out, dateTime, format);
                } else if (out.isEnabled(SerializerFeature.WriteDateUseDateFormat)) {
                    //使用固定格式转化时间
                    write(out, dateTime, JSON.DEFFAULT_DATE_FORMAT);
                } else {
                    out.writeLong(dateTime.atZone(JSON.defaultTimeZone.toZoneId()).toInstant().toEpochMilli());
                }
            } else {
                out.writeString(object.toString());
            }
        }
    }

紧跟这在分析一下v1.2.49代码逻辑

 public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
                      int features) throws IOException {
        SerializeWriter out = serializer.out;
        if (object == null) {
            out.writeNull();
        } else {
            if (fieldType == null) {
                fieldType = object.getClass();
            }

            if (fieldType == LocalDateTime.class) {
                final int mask = SerializerFeature.UseISO8601DateFormat.getMask();
                LocalDateTime dateTime = (LocalDateTime) object;
                String format = serializer.getDateFormatPattern();

                if (format == null) {
                    if ((features & mask) != 0 || serializer.isEnabled(SerializerFeature.UseISO8601DateFormat)) {
                        format = formatter_iso8601_pattern;
                    } else {
                        int nano = dateTime.getNano();
                        //v1.2.49版本,很明显变化很大,默认日期格式
                        if (nano == 0) {
                            format = formatter_iso8601_pattern;
                        } else if (nano % 1000000 == 0) {
                            format = formatter_iso8601_pattern_23;
                        } else {
                            format = formatter_iso8601_pattern_29;
                        }
                    }
                }

                if (format != null) {
                    write(out, dateTime, format);
                } else if (out.isEnabled(SerializerFeature.WriteDateUseDateFormat)) {
                    //使用固定格式转化时间
                    write(out, dateTime, JSON.DEFFAULT_DATE_FORMAT);
                } else {
                    out.writeLong(dateTime.atZone(JSON.defaultTimeZone.toZoneId()).toInstant().toEpochMilli());
                }
            } else {
                out.writeString(object.toString());
            }
        }
    }

        当然我上述编码不规范,造成了日期格式转换错误,我把它拿出来说事,第一,组件基础原理的研究可以让我们更好的使用它,第二,我们在做开发或者其他事情的时候,不要强依赖第三方组件提供可靠的保障,数据存储和提取一定要严格而明确指定统一的格式,而不管组件默认是什么样的格式!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值