[转载]JSON Date Format – 经世沉淀 – 博客频道 – CSDN.NET.
JSON 是一种流行地、广泛地应用于Internet的数据格式,相对于XML而言,它更小、解析更快。但可能就是由于“小”,JSON规范并没有定义如何序列化 日期。尽管在社区已经有了很多这方面的讨论,但规范仍然未形成。争论的焦点在于日期序列化是否应直接采用数字或者ISO字符串日期,还是应该采用特殊分隔 符标记的字符串日期。因为如果没有分隔符,就没法自我描述自身是一个日期类型。先搁置争议,就各AJAX库和JSON库封装的日期格式作统一讨论。
(1)直接数字型日期。
因为 JavaScript 的时间类型是从1970年1月1日以来的毫秒数。这有点类似UNIX/Linux的时间是1970年1月1日以来的秒数。当然,为支持国际化,这里的1970年1月1日的毫秒数是UTC(GMT)格林威治时间。
如:
- {Date: new Date(1278903921551)}
JavaScript Parser:
- var obj = eval(‘(‘ + “{Date: new Date(1278903921551)}” + ‘)’);
- var dateValue = obj[“Date”];
C# Parser:
- long dateNumber = 1278903921551;
- long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
- DateTime dateValue = new DateTime(beginTicks + dateNumber * 10000);
(2)直接字符串日期。
字符串日期,常见的是ISO8601 标准。
如:
- {Date:“2010-07-12T03:05:21Z”}
JavaScript Parser:
- // Parse JSON string value when the string value is ISO Date Format
- var obj = eval(‘(‘ + ‘{Date:”2010-07-12T03:05:21Z”}’ + ‘)’);
- scanDate(obj, isoDateParser);
- var dateValue = obj[“Date”];
- function scanDate(obj, dateParser) {
- for (var key in obj) {
- obj[key] = dateParser(key, obj[key]);
- if (typeof (obj[key]) === ‘object’) {
- scanDate(obj[key], dateParser);
- }
- }
- }
- function isoDateParser(key, value) {
- if (typeof value === ‘string’) {
- var a = /^(/d{4})-(/d{2})-(/d{2})T(/d{2}):(/d{2}):(/d{2}(?:/./d*)?)(?:([/+-])(/d{2})/:(/d{2}))?Z?$/.exec(value);
- if (a) {
- Var utcMilliseconds = Date.UTC(+a[1], +a[2] – 1, +a[3], +a[4], +a[5], +a[6]);
- return new Date(utcMilliseconds);
- }
- }
- return value;
- }
C# Parser:
string dateString = “2010-07-12T03:05:21Z” DateTime dateValue = DateTime.Parse(dateString);
(3)带分隔符的数字日期。
- /Date(NUMBER(+/-)TZD)/
- “//Date(NUMBER(+/-)TZD)//”
NUMBER是1970年1月1日以来的毫秒数,TZD是4位数时区的。+和-表示东、西时区。如果没有时区,则NUMBER是UTC时间。用 /Date()/分隔。//和//是对/的转义。JSON.NET和Microsoft AJAX Library用的就是这种格式。中间的数字也是格林威治时间1970年1月1日以来的毫秒数。和第一种不同是没有采用JavaScript的日期构造 器,而是采用了一种自定义的分隔符。
如:”//Date(1278903921551)//”。
JavaScript Parser:
- var obj = eval(‘(‘ + “{Date: //Date(1278903921551)//}”.replace(///Date/((/d+)/)///gi, “new Date($1)”) + ‘)’);
- var dateValue = obj[“Date”];
C# Parser:
- string dateString = “///Date(1278903921551)///”;
- int startPos = dateString.IndexOf(“(“)+1;
- int endPos = dateString.LastIndexOf(“)”)-1;
- long dateNumber = long.Parse(dateString.Substring(startPos, endPos – startPos + 1));
- long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
- DateTime dateValue = new DateTime(beginTicks + dateNumber * 10000);
如:”//Date(1278903921551+0800)//”。
JavaScript Parser:
- // Parse JSON string value when the string value is JSON Date Format
- var obj = eval(‘(‘ + ‘{Date://Date(1278903921551+0800)//}’ + ‘)’);
- scanDate(obj, jsonDateParser);
- var dateValue = obj[“Date”];
- function scanDate(obj, dateParser) {
- for (var key in obj) {
- obj[key] = dateParser(key, obj[key]);
- if (typeof (obj[key]) === ‘object ‘) {
- scanDate(obj[key], dateParser);
- }
- }
- }
- function jsonDateParser(key, value) {
- if (typeof value === ‘string’ ) {
- var a = (/^///Date/((/d+)([/+/-](/d/d)(/d/d))?/)///gi).exec(value);
- if (a) {
- var utcMilliseconds = parseInt(a[1], 10) + ((a[3] == ‘-‘) ? -1 : 1) * (parseInt(a[4], 10) + (parseInt(a[5], 10) / 60.0)) * 60 * 60 * 1000;
- return new Date(utcMilliseconds);
- }
- }
- return value;
- }
C# Parser:
- string dateString = “///Date(1278903921551+0800)///”;
- int startPos = dateString.IndexOf(“(“) + 1;
- int endPos = dateString.LastIndexOf(“)”) – 1;
- string dateNumberString = dateString.Substring(startPos, endPos – startPos + 1);
- int timeZoneMilSeconds = 0;
- int? timeZoneIndex = null;
- if (dateNumberString.IndexOf(“+”) > -1) {
- timeZoneIndex = dateNumberString.IndexOf(“+”);
- timeZoneMilSeconds = 1;
- }
- if (dateNumberString.IndexOf(“-“) > -1) {
- timeZoneIndex = dateNumberString.IndexOf(“-“);
- timeZoneMilSeconds = -1;
- }
- long dateNumber = 0;
- if (timeZoneIndex.HasValue) {
- timeZoneMilSeconds = timeZoneMilSeconds * (int)((int.Parse(dateNumberString.Substring(timeZoneIndex.Value + 1).Substring(0, 2))
- + int.Parse(dateNumberString.Substring(timeZoneIndex.Value + 1).Substring(2)) / 60.0) * 60 * 60 * 1000);
- dateNumber = long.Parse(dateNumberString.Substring(0, timeZoneIndex.Value)) + timeZoneMilSeconds;
- } else {
- dateNumber = long.Parse(dateNumberString);
- }
- long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks;
- DateTime dateValue = new DateTime(beginTicks + dateNumber * 10000);
以上就是常见的JSON的日期格式了。JSON库或者一些AJAX库已经封装了相应的JavaScript的日期的支持,在解析时应直接使用JSON库自带的解析器。如果需要自定义解析这些日期,可参考上述JavaScript和C#代码。