代码改变世界

JSON Date Format

2011-12-10 21:53  clarkhan  阅读(649)  评论(0编辑  收藏  举报

JSON 是一种流行地、广泛地应用于Internet的数据格式,相对于XML而言,它更小、解析更快。但可能就是由于“小”,JSON规范并没有定义如何序列化日期。尽管在社区已经有了很多这方面的讨论,但规范仍然未形成。争论的焦点在于日期序列化是否应直接采用数字或者ISO字符串日期,还是应该采用特殊分隔符标记的字符串日期。因为如果没有分隔符,就没法自我描述自身是一个日期类型。先搁置争议,就各AJAX库和JSON库封装的日期格式作统一讨论。

(1)直接数字型日期。

因为 JavaScript 的时间类型是从1970年1月1日以来的毫秒数。这有点类似UNIX/Linux的时间是1970年1月1日以来的秒数。当然,为支持国际化,这里的1970年1月1日的毫秒数是UTC(GMT)格林威治时间。

如:

 
  1. {Date: new Date(1278903921551)} 

JavaScript Parser:

 
  1. var obj = eval('(' + "{Date: new Date(1278903921551)}" + ')'); 
  2. var dateValue = obj["Date"]; 

C# Parser:

 
  1. long dateNumber = 1278903921551; 
  2. long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; 
  3. DateTime dateValue = new DateTime(beginTicks + dateNumber * 10000); 

(2)直接字符串日期。

字符串日期,常见的是ISO8601 标准。

如:

 
  1. {Date:"2010-07-12T03:05:21Z"

JavaScript Parser:

 
  1. // Parse JSON string value when the string value is ISO Date Format 
  2. var obj = eval('(' + '{Date:"2010-07-12T03:05:21Z"}' + ')'); 
  3. scanDate(obj, isoDateParser); 
  4. var dateValue = obj["Date"]; 
  5. function scanDate(obj, dateParser) {     
  6.     for (var key in obj) {       
  7.         obj[key] = dateParser(key, obj[key]);        
  8.         if (typeof (obj[key]) === 'object') {            
  9.             scanDate(obj[key], dateParser); 
  10.         } 
  11.     } 
  12. function isoDateParser(key, value) {     
  13.     if (typeof value === 'string') {         
  14.         var a = /^(/d{4})-(/d{2})-(/d{2})T(/d{2}):(/d{2}):(/d{2}(?:/./d*)?)(?:([/+-])(/d{2})/:(/d{2}))?Z?$/.exec(value);         
  15.         if (a) {             
  16.             Var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);             
  17.             return new Date(utcMilliseconds);         
  18.         }     
  19.     }     
  20.     return value; 

C# Parser:

string dateString = "2010-07-12T03:05:21Z" DateTime dateValue = DateTime.Parse(dateString);

(3)带分隔符的数字日期。

 
  1. /Date(NUMBER(+/-)TZD)/ 
 
  1. "//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:

 
  1. var obj = eval('(' + "{Date: //Date(1278903921551)//}".replace(///Date/((/d+)/)///gi, "new Date($1)") + ')'); 
  2. var dateValue = obj["Date"]; 

C# Parser:

 
  1. string dateString = "///Date(1278903921551)///"
  2. int startPos = dateString.IndexOf("(")+1; 
  3. int endPos = dateString.LastIndexOf(")")-1; 
  4. long dateNumber = long.Parse(dateString.Substring(startPos, endPos - startPos + 1)); 
  5. long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; 
  6. DateTime dateValue = new DateTime(beginTicks + dateNumber * 10000); 

如:"//Date(1278903921551+0800)//"。

JavaScript Parser:

 
  1. // Parse JSON string value when the string value is JSON Date Format 
  2. var obj = eval('(' + '{Date://Date(1278903921551+0800)//}' + ')'); 
  3. scanDate(obj, jsonDateParser); 
  4. var dateValue = obj["Date"]; 
  5. function scanDate(obj, dateParser) { 
  6.     for (var key in obj) { 
  7.         obj[key] = dateParser(key, obj[key]); 
  8.         if (typeof (obj[key]) === 'object ') { 
  9.             scanDate(obj[key], dateParser); 
  10.         } 
  11.     } 
  12. function jsonDateParser(key, value) {      
  13.     if (typeof value === 'string' ) {          
  14.         var a = (/^///Date/((/d+)([/+/-](/d/d)(/d/d))?/)///gi).exec(value); 
  15.         if (a) { 
  16.             var utcMilliseconds = parseInt(a[1], 10) + ((a[3] == '-') ? -1 : 1) * (parseInt(a[4], 10) + (parseInt(a[5], 10) / 60.0)) * 60 * 60 * 1000; 
  17.             return new Date(utcMilliseconds); 
  18.         } 
  19.     } 
  20.     return value; 

C# Parser:

 
  1. string dateString = "///Date(1278903921551+0800)///"
  2. int startPos = dateString.IndexOf("(") + 1; 
  3. int endPos = dateString.LastIndexOf(")") - 1; 
  4. string dateNumberString = dateString.Substring(startPos, endPos - startPos + 1); 
  5. int timeZoneMilSeconds = 0; 
  6. int? timeZoneIndex = null
  7. if (dateNumberString.IndexOf("+") > -1) { 
  8.     timeZoneIndex = dateNumberString.IndexOf("+"); 
  9.     timeZoneMilSeconds = 1; 
  10. if (dateNumberString.IndexOf("-") > -1) { 
  11.     timeZoneIndex = dateNumberString.IndexOf("-"); 
  12.     timeZoneMilSeconds = -1; 
  13. long dateNumber = 0; 
  14. if (timeZoneIndex.HasValue) { 
  15.     timeZoneMilSeconds = timeZoneMilSeconds * (int)((int.Parse(dateNumberString.Substring(timeZoneIndex.Value + 1).Substring(0, 2)) 
  16.                     + int.Parse(dateNumberString.Substring(timeZoneIndex.Value + 1).Substring(2)) / 60.0) * 60 * 60 * 1000); 
  17.     dateNumber = long.Parse(dateNumberString.Substring(0, timeZoneIndex.Value)) + timeZoneMilSeconds; 
  18. } else
  19.     dateNumber = long.Parse(dateNumberString); 
  20. long beginTicks = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; 
  21. DateTime dateValue = new DateTime(beginTicks + dateNumber * 10000); 

以上就是常见的JSON的日期格式了。JSON库或者一些AJAX库已经封装了相应的JavaScript的日期的支持,在解析时应直接使用JSON库自带的解析器。如果需要自定义解析这些日期,可参考上述JavaScript和C#代码。

注:本文转载自http://blog.csdn.net/hellotianma/article/details/5728723