You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jackson序列化Java Date至Unity JsonUtility解析失败,咨询可行方案及性能影响

解决Java Jackson与Unity JsonUtility的日期解析兼容问题

问题描述

我最近在做Spring Boot后端和Unity前端的对接时,碰到了一个日期解析的坑:后端用Jackson序列化的Date字段,前端用Unity的JsonUtility始终解析成1970年的默认空日期。具体情况如下:

  • 后端返回的JSON日期格式:{"aDate": "2018-05-18T22:35:47.760+0000"}
  • 前端解析后,dateObject.aDate总是显示1970-01-01

我现在有两个疑问:

  1. 是不是必须把日期转换成毫秒数(长整型)来传输?
  2. 如果要自定义Jackson的序列化/反序列化器,会不会带来明显的性能损耗?

问题分析与解决方案

为什么解析失败?

Unity的JsonUtility对日期格式的支持非常有限,它只兼容特定格式的ISO 8601字符串,比如yyyy-MM-ddTHH:mm:ss或者带标准时区标识的yyyy-MM-ddTHH:mm:ss.SSSZ。而Jackson默认输出的2018-05-18T22:35:47.760+0000格式(时区用+0000而不是Z),JsonUtility完全无法识别,所以直接返回了DateTime的默认值。

可选的兼容方案

你有两个靠谱的选择,不需要纠结必须用毫秒数:

方案一:转成毫秒级时间戳传输(最稳妥)

这种方式彻底规避了格式兼容问题,前后端处理都简单直接。

后端配置(Jackson注解实现)

给Date字段添加@JsonFormat注解,指定序列化为数字类型的时间戳:

import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

@Data
public class Backend {
    // 序列化为毫秒级时间戳
    @JsonFormat(shape = JsonFormat.Shape.NUMBER)
    private Date aDate;

    public Backend() {
        this.aDate = new Date();
    }
}

修改后,后端返回的JSON会变成:

{"aDate": 1526663747760}
前端Unity解析逻辑

把C#类中的DateTime字段改成long,然后手动转换为DateTime:

using System;
[Serializable]
public class FrontEnd {
    public long aDate;
    
    // 新增转换方法,把时间戳转成UTC时间
    public DateTime GetUtcDateTime() {
        return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
            .AddMilliseconds(aDate);
    }
    
    // 如果需要本地时间,可以再封装一个方法
    public DateTime GetLocalDateTime() {
        return GetUtcDateTime().ToLocalTime();
    }
}

// 解析代码示例
private IEnumerator AcceptWww(WWW www) {
    yield return www;
    var dateObject = JsonUtility.FromJson<FrontEnd>(www.text);
    DateTime actualDate = dateObject.GetUtcDateTime();
    // 现在actualDate就是正确的日期了
}

方案二:修改Jackson输出格式适配Unity

如果不想改变数据类型,可以让Jackson输出JsonUtility能识别的标准ISO 8601格式:

import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

@Data
public class Backend {
    // 输出Unity兼容的ISO 8601格式,时区设为UTC
    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
    private Date aDate;

    public Backend() {
        this.aDate = new Date();
    }
}

修改后,后端返回的JSON会是:

{"aDate": "2018-05-18T22:35:47.760Z"}

此时前端不需要修改FrontEnd类,JsonUtility就能直接正确解析这个日期字符串。

关于自定义序列化的性能损耗

完全不用焦虑!Jackson的注解式序列化(比如@JsonFormat)是框架原生支持的特性,性能和默认序列化几乎没有差距,损耗可以忽略不计。

就算是自己编写自定义的JsonSerializer类,只要逻辑不复杂(比如只是简单的格式转换),性能也不会有明显下降——Jackson的扩展机制设计得非常高效,不会成为接口的性能瓶颈。


内容的提问来源于stack exchange,提问作者Codehai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:25:56