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

.NET序列化JSON与Moment.js解析DateTime日期差一天问题排查

问题原因

这是时区不匹配导致的序列化/解析偏差,具体细节:

  1. .NET默认的JsonResult序列化DateTime时,会将本地时间转换为UTC时间的毫秒时间戳(以1970-01-01 UTC为基准)。假设数据库中的1952-05-17 00:00:00是本地时区(比如东八区),序列化后会转成UTC时间1952-05-16 16:00:00,对应的时间戳就是-556250400000。
  2. Moment.js解析该时间戳时,默认会按客户端本地时区处理。如果客户端时区与后端时区不一致(或Moment误将UTC时间戳当成本地时间戳解析),就会出现日期偏移一天的情况。
修复方案

可从后端序列化或客户端解析两个方向入手:

方案一:修改后端序列化规则(推荐)

让.NET输出带时区信息的ISO 8601格式日期,避免时间戳带来的时区歧义:

// 使用Newtonsoft.Json配置序列化规则
var jsonSettings = new Newtonsoft.Json.JsonSerializerSettings
{
    DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffK", // 带时区偏移的ISO格式
    DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local // 保留本地时区信息
};
return Json(new { data = dataFiltered, recordsFiltered = dataTotal, recordsTotal = dataTotal }, jsonSettings);

客户端收到的日期格式类似"1952-05-17T00:00:00+08:00",Moment可以直接正确解析:

moment(value).format("DD/MM/YYYY"); // 输出17/05/1952

方案二:客户端修正解析逻辑

如果无法修改后端,可在客户端明确按UTC解析时间戳,再转换为目标格式:

// 从/Date(-556250400000)/中提取时间戳数字
const timestamp = Number(value.replace(/\/Date\((-?\d+)\)\//, '$1'));
// 按UTC解析后格式化
moment.utc(timestamp).format("DD/MM/YYYY"); // 输出17/05/1952
// 若需要转换为客户端本地时区,再加.local()
moment.utc(timestamp).local().format("DD/MM/YYYY");

方案三:后端直接输出日期字符串

查询数据时将DateTime直接转为固定格式的字符串,跳过序列化的时区转换:

// 示例:将数据中的日期字段转为字符串
var processedData = dataFiltered.Select(item => new 
{
    // 保留其他字段
    item.Id,
    item.Name,
    // 日期字段直接转字符串
    TargetDate = item.TargetDate.ToString("yyyy-MM-dd")
});
return Json(new { data = processedData, recordsFiltered = dataTotal, recordsTotal = dataTotal });

客户端收到的是纯日期字符串,直接格式化或显示即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 11:03:37