Fastjson1 日期格式化与反序列化

作为 Java 开发者,处理日期时间格式是日常开发中的常见需求。Fastjson 1.x 版本虽然已经停止更新,但仍在许多遗留系统中广泛使用。本文介绍 Fastjson 1 中日期格式化与反序列化的核心技巧。

日期序列化

默认序列化行为

假设我们有一个包含日期字段的 Java 对象:

import com.alibaba.fastjson.JSON;
import java.util.Date;

public class User {
    private String name;
    private Date birthDate;

    // getter、setter 省略
}

// 测试
User user = new User();
user.setName("张三");
user.setBirthDate(new Date());

String json = JSON.toJSONString(user);
System.out.println(json);
{"birthDate":1778589745271,"name":"张三"}

默认情况下,Fastjson 将 Date 序列化为时间戳(毫秒数),这通常不符合业务要求,下面介绍使用注解的方式格式化日期。

使用 @JSONField 注解格式化日期

解决方案是使用 @JSONField 注解指定日期格式:

import com.alibaba.fastjson.annotation.JSONField;

public class User {
    private String name;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private Date birthDate;

    // getter、setter...
}

// 再次序列化
String json = JSON.toJSONString(user);
// 输出:{"birthDate":"2026-05-12 20:43:34","name":"张三"}

常用格式模板:

  • yyyy.MM.dd → 2026.05.15
  • yyyyMMdd→ 20260515
  • yyyyMMddHHmmss→ 20260515143000
  • yyyy-MM-dd HH:mm→ 2026-05-15 14:30
  • yyyy/MM/dd HH:mm:ss→ 2026/05/15 14:30:00
  • yyyy.MM.dd HH:mm:ss → 2026.05.15 14:30:00
  • yyyy-MM-dd HH:mm:ss.SSS → 2026-05-15 14:30:00.123
  • yyyy-MM-dd'T'HH:mm:ss → 2026-05-15T14:30:00
  • MM-dd-yyyy→ 05-15-2026
  • dd-MM-yyyy→ 15-05-2026
  • yyyy年MM月dd日 → 2026年05月15日
  • yyyy年MM月dd日 HH时mm分ss秒 → 2026年05月15日 14时30分00秒

反序列化日期字符串

将 JSON 字符串转为对象

当 JSON 中包含日期字符串时,Fastjson 能自动识别并反序列化:

String jsonStr = "{\"name\":\"李四\",\"birthDate\":\"2026-06-01 10:20:30\"}";

User user = JSON.parseObject(jsonStr, User.class);
System.out.println(user.getBirthDate());
// Mon Jun 01 10:20:30 CST 2026

注意:反序列化时,JSON 字符串中的日期格式必须与 @JSONField 中定义的 format 一致。

灵活处理多种日期格式

如果 JSON 中可能出现不同的日期格式,可以通过 SerializerFeature 全局配置:

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.parser.Feature;

// 全局配置日期格式(方式一)
JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
// 注意:Fastjson 1 中属性名是 DEFFAULT_DATE_FORMAT(两个F)
// 实际应为:DEFAULT_DATE_FORMAT,这里为保持历史写法,请确认版本

// 更推荐的方式:在解析时指定
String jsonDate1 = "{\"birthDate\":\"2025-01-01\"}";
User user1 = JSON.parseObject(jsonDate1, User.class, 
    new Feature[]{Feature.AllowUnQuotedFieldNames}); // 可省略

// 或者使用自定义解析器(高级用法略)

常见问题与解决技巧

时间戳与字符串混合处理

// 接收时间戳格式
String jsonWithTimestamp = "{\"birthDate\":1778589943000}";
User user = JSON.parseObject(jsonWithTimestamp, User.class); 
// 即使 @JSONField 定义了 format,也会自动解析时间戳

时区问题

Fastjson 默认使用系统时区。如需指定时区:

import com.alibaba.fastjson.JSON;
import java.util.TimeZone;

JSON.defaultTimeZone = TimeZone.getTimeZone("GMT+8");
// 或在序列化时指定:
String json = JSON.toJSONString(user, 
    SerializerFeature.WriteDateUseDateFormat);

完整示例

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import java.util.Date;

public class DateExample {
    public static void main(String[] args) {
        // 1. 序列化:Date → JSON
        Order order = new Order();
        order.setId(1001);
        order.setPayTime(new Date());

        String json = JSON.toJSONString(order);
        System.out.println("序列化结果:" + json);
        // 输出:{"id":1001,"payTime":"2026-05-15 14:30:00"}

        // 2. 反序列化:JSON → Object
        String input = "{\"id\":1002,\"payTime\":\"2026-05-15 08:00:00\"}";
        Order parsed = JSON.parseObject(input, Order.class);
        System.out.println("反序列化结果:");
        System.out.println("ID: " + parsed.getId());
        System.out.println("支付时间: " + parsed.getPayTime());
    }
}

class Order {
    private int id;

    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private Date payTime;

    // getter/setter 省略...
}

总结

掌握 Fastjson 1 的日期处理,关键记住三点:

  1. 序列化时使用 @JSONField(format="...") 自定义格式
  2. 反序列化时格式需与定义完全一致
  3. 全局配置可通过 JSON.DEFFAULT_DATE_FORMAT 设置(注意拼写历史问题)

虽然 Fastjson 1 已停止维护,但理解这些基础对阅读老代码或迁移到 Fastjson 2 仍然非常有帮助。