如何将ASP.NET Ajax返回带UTC偏移的DateTime转为JS指定目标日期
问题解析与解决方法
首先我帮你理清楚为什么会出现这个时间偏移的问题:
为什么会自动添加UTC偏移?
你在C#里的DateTime值"2019-05-04"其实是本地时区时间(看起来你的环境是东九区,也就是UTC+9)。ASP.NET在序列化这类DateTime时,默认会把它转换成带时区偏移的特殊JSON格式/Date(timestamp+offset)/——这里的1556895600000是该本地时间对应的UTC时间戳(也就是东九区5月4日0点,对应UTC时间5月3日15点的毫秒数),+0900就是你的本地时区相对于UTC的偏移量。
而你现在的代码只提取了时间戳数字,完全忽略了后面的偏移量,导致JavaScript的Date对象直接把这个时间戳当成UTC时间来解析,所以输出的是UTC时间2019-05-03T15:00:00.000Z,自然和你想要的本地日期不符。
几种解决方法,挑适合你的用:
方法1:正确解析带偏移量的ASP.NET日期格式
不要只提取时间戳,把偏移量也纳入计算,这样能准确还原本地时间:
const aspNetDate = "/Date(1556895600000+0900)/"; // 匹配时间戳和偏移量 const matchResult = aspNetDate.match(/\/Date\((\d+)([+-]\d{4})\)\//); if (matchResult) { const timestamp = parseInt(matchResult[1], 10); const offset = parseInt(matchResult[2], 10); // +0900会被解析为900 // 把偏移量转换成毫秒(9小时 = 9*60*60*1000毫秒) const offsetMs = (offset / 100) * 60 * 60 * 1000; // 计算本地时间的时间戳并生成Date对象 const localDate = new Date(timestamp + offsetMs); // 格式化为你要的"yyyy-MM-dd"格式 const formatted = `${localDate.getFullYear()}-${String(localDate.getMonth()+1).padStart(2, '0')}-${String(localDate.getDate()).padStart(2, '0')}`; console.log(formatted); // 输出 "2019-05-04" }
方法2:利用本地时区自动转换(最简单的快速解决)
其实你当前得到的Date对象已经包含了正确的本地时间信息,只是默认输出的是UTC格式。你可以直接用Date的本地时间方法来提取年月日:
const d = new Date(("/Date(1556895600000+0900)/").match(/\d+/)[0] * 1); const year = d.getFullYear(); // 月份是从0开始计数的,所以要+1后补零 const month = String(d.getMonth() + 1).padStart(2, '0'); // getDate()返回的是本地时区的日期 const day = String(d.getDate()).padStart(2, '0'); const targetDate = `${year}-${month}-${day}`; console.log(targetDate); // 输出 "2019-05-04"
这个方法的前提是你的前端运行环境的时区和后端一致(都是东九区),如果用户可能在不同时区访问,那还是用方法1更准确。
方法3:从后端修改序列化规则(一劳永逸)
如果能修改C#后端代码,可以直接避免前端的解析麻烦:
- 返回字符串格式的日期:把
DateTime属性转换成string类型,格式化为"yyyy-MM-dd",比如date.ToString("yyyy-MM-dd"),前端拿到直接就是你要的日期字符串,不需要处理Date对象。 - 返回UTC时间:把
DateTime转换成UTC时间再序列化,比如date.ToUniversalTime(),这样返回的格式是/Date(1556895600000)/(不带偏移),前端解析后可以根据需要转换成本地时间。
内容的提问来源于stack exchange,提问作者Hong Van Vit
相关产品推荐
相关产品推荐

