如何格式化Microsoft JSON日期
技术背景
JSON 本身没有内置的日期类型,Microsoft JSON 日期通常采用 /Date(milliseconds)/
这种格式,其中 milliseconds
表示自 1970 年 1 月 1 日午夜(UTC)以来的毫秒数。在处理这类日期时,需要将其转换为 JavaScript 的 Date
对象,以便进行后续操作。
实现步骤
基本转换方法
可以通过提取毫秒数并使用 Date
构造函数来实现转换:
1 2
| var jsonDate = "/Date(1224043200000)/"; var date = new Date(parseInt(jsonDate.substr(6)));
|
上述代码中,substr(6)
用于去除 /Date(
部分,parseInt
用于将提取的字符串转换为整数,最后传递给 Date
构造函数创建日期对象。
处理带时区偏移的日期
在 WCF 服务中返回的日期可能包含时区偏移,如 /Date(1224043200000-0600)/
。可以使用正则表达式来处理这种情况:
1 2
| var jsonDate = "/Date(1224043200000-0600)/"; var date = new Date(parseInt(jsonDate.replace(/\/Date\((.*?)\)\//gi, "$1")));
|
自动解析日期
可以扩展 jQuery 的 $.parseJSON()
方法,使其能够自动解析日期:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| (function () { var DATE_START = "/Date("; var DATE_START_LENGTH = DATE_START.length;
function isDateString(x) { return typeof x === "string" && x.startsWith(DATE_START); }
function deserializeDateString(dateString) { var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH))); var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000); return utcDate; }
function convertJSONDates(key, value) { if (isDateString(value)) { return deserializeDateString(value); } return value; }
window.jQuery.ajaxSetup({ converters: { "text json": function (data) { return window.JSON.parse(data, convertJSONDates); } } }); }());
|
使用第三方库
可以使用 moment.js
库来处理日期:
1 2
| var jsonDate = "/Date(1224043200000)/"; var d = moment(jsonDate);
|
核心代码
格式化日期为指定格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function formatDate(d) { if (hasTime(d)) { var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear(); s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds()); } else { var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear(); }
return s; }
function hasTime(d) { return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds()); }
function zeroFill(n) { if ((n + '').length == 1) { return '0' + n; } return n; }
|
统一解析日期函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| function looksLikeMSDate(s) { return /^\/Date\(/.test(s); }
var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/; function looksLikeIsoDate(s) { return isoDateRegex.test(s); }
function parseMSDate(s) { return new Date(parseInt(s.substr(6))); }
function parseIsoDate(s) { var m = isoDateRegex.exec(s); if (m.length == 7 || (m.length > 7 && (!m[7] || m[7].charAt(0) != '.' || !m[8] || m[8] == 'Z'))) { var d = new Date(Date.UTC(m[1], m[2] - 1, m[3], m[4], m[5], m[6])); } else { var d = new Date(m[1], m[2] - 1, m[3], m[4], m[5], m[6]); } return d; }
function parseDate(s) { var d; if (looksLikeMSDate(s)) { d = parseMSDate(s); } else if (looksLikeIsoDate(s)) { d = parseIsoDate(s); } else { return null; } return formatDate(d); }
|
最佳实践
- 优先使用 ISO 8601 格式:ISO 8601 格式是一种标准化的日期和时间表示方法,JavaScript 的
Date
构造函数可以直接处理这种格式,无需额外解析。例如:
1 2
| var jsonDate = "2025-05-21T12:00:00Z"; var date = new Date(jsonDate);
|
- 使用第三方库:
moment.js
等第三方库提供了丰富的日期处理功能,能够简化日期解析和格式化的过程,同时支持多种本地化格式。 - 考虑时区问题:在处理日期时,要注意时区的影响。可以将日期统一转换为 UTC 时间进行处理,避免因时区差异导致的问题。
常见问题
时区问题
Microsoft JSON 日期可能没有明确的时区信息,而 JavaScript 的 Date
对象会根据本地时区进行解释。因此,在处理日期时,需要考虑时区的转换。可以使用 Date.UTC()
方法创建 UTC 时间的日期对象。
正则表达式匹配问题
不同的 Microsoft JSON 日期格式可能会有所不同,如 /Date(1224043200000)/
、/Date(1224043200000-0600)/
等。在使用正则表达式进行匹配时,需要确保正则表达式能够覆盖所有可能的格式。
兼容性问题
不同的浏览器对日期解析的支持可能会有所不同。在使用某些日期解析方法时,需要进行兼容性测试,确保在各种浏览器中都能正常工作。