2010-08-23 14:06:38| 分类: js | 标签: |字号大中小 订阅
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#代码。
原文链接:http://blog.csdn.net/hellotianma/article/details/5728723