动机:.net 默认的时间序列化方式为\/Date(数字 时区)\/,序列化成JSON在前端很难处理,有没有一种好的处理方式呢?
改进:
1 JSON = new function(){ 2 this.decode = function(){ 3 var filter, result, self, tmp; 4 if($$("toString")) { 5 switch(arguments.length){ 6 case 2: 7 self = arguments[0]; 8 filter = arguments[1]; 9 break; 10 case 1: 11 if($[typeof arguments[0]](arguments[0]) === Function) { 12 self = this; 13 filter = arguments[0]; 14 } 15 else 16 self = arguments[0]; 17 break; 18 default: 19 self = this; 20 break; 21 }; 22 if(rc.test(self)){ 23 try{ 24 result = e("(".concat(self, ")")); 25 if(filter && result !== null && (tmp = $[typeof result](result)) && (tmp === Array || tmp === Object)){ 26 for(self in result) 27 result[self] = v(self, result) ? filter(self, result[self]) : result[self]; 28 } 29 } 30 catch(z){} 31 } 32 else { 33 throw new Error("bad data"); 34 } 35 }; 36 return result; 37 }; 38 this.encode = function(){ 39 var self = arguments.length ? arguments[0] : this, 40 result, tmp; 41 if(self === null) 42 result = "null"; 43 else if(self !== undefined && (tmp = $[typeof self](self))) { 44 switch(tmp){ 45 case Array: 46 result = []; 47 for(var i = 0, j = 0, k = self.length; j < k; j++) { 48 if(self[j] !== undefined && (tmp = JSON.encode(self[j]))) 49 result[i++] = tmp; 50 }; 51 result = "[".concat(result.join(","), "]"); 52 break; 53 case Boolean: 54 result = String(self); 55 break; 56 case Date: 57 result = '"\\/Date('.concat(self.valueOf(),')\\/"'); 58 break; 59 case Function: 60 break; 61 case Number: 62 result = isFinite(self) ? String(self) : "null"; 63 break; 64 case String: 65 result = '"'.concat(self.replace(rs, s).replace(ru, u), '"'); 66 break; 67 default: 68 var i = 0, key; 69 result = []; 70 for(key in self) { 71 if(self[key] !== undefined && (tmp = JSON.encode(self[key]))) 72 result[i++] = '"'.concat(key.replace(rs, s).replace(ru, u), '":', tmp); 73 }; 74 result = "{".concat(result.join(","), "}"); 75 break; 76 } 77 }; 78 return result; 79 }; 80 this.toDate = function(){ 81 var self = arguments.length ? arguments[0] : this, 82 result=self; 83 if(rd.test(self)){ 84 result = new Date(); 85 result.setHours(i(self, 11, 2)); 86 result.setMinutes(i(self, 14, 2)); 87 result.setSeconds(i(self, 17, 2)); 88 result.setMonth(i(self, 5, 2) - 1); 89 result.setDate(i(self, 8, 2)); 90 result.setFullYear(i(self, 0, 4)); 91 } 92 //else if(rt.test(self)) 93 //result = new Date(self * 1000); 94 else if(rr.test(self)){ 95 result=new Date(self.match(/\d+/)[0]-0); 96 } 97 return result; 98 }; 99 100 this.defaultDateFilter=function(k,m){ // 提供通用的时间字符串解析方式(尽可能利用原有处理机制,这一过程较消耗性能,需要解析时间时使用filter) 101 switch($[typeof m](m)){ 102 case Array: 103 case Object: 104 for(var p in m){ 105 m[p]=v(p,m)?arguments.callee(p,m[p]):m[p]; 106 } 107 return m; 108 case String: 109 return JSON.toDate(m); 110 default: 111 return m; 112 } 113 } 114 var c = {"\b":"b","\t":"t","\n":"n","\f":"f","\r":"r",'"':'"',"\\":"\\","/":"/"}, 115 d = function(n){return n<10?"0".concat(n):n}, 116 e = function(c,f,e){e=eval;delete eval;if(typeof eval==="undefined")eval=e;f=eval(""+c);eval=e;return f}, 117 i = function(e,p,l){return 1*e.substr(p,l)}, 118 p = ["","000","00","0",""], 119 rc = null, 120 rd = /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$/, 121 rs = /(\x5c|\x2F|\x22|[\x0c-\x0d]|[\x08-\x0a])/g, 122 rr=/^\/Date\(\d+\)\/$/, 123 rt = /^([0-9]+|[0-9]+[,\.][0-9]{1,3})$/, 124 ru = /([\x00-\x07]|\x0b|[\x0e-\x1f])/g, 125 s = function(i,d){return "\\".concat(c[d])}, 126 u = function(i,d){ 127 var n=d.charCodeAt(0).toString(16); 128 return "\\u".concat(p[n.length],n) 129 }, 130 v = function(k,v){return $[typeof v[k]](v[k])!==Function&&(v.hasOwnProperty?v.hasOwnProperty(k):v.constructor.prototype[k]!==v[k])}, 131 $ = { 132 "boolean":function(){return Boolean}, 133 "function":function(){return Function}, 134 "number":function(){return Number}, 135 "object":function(o){return o instanceof o.constructor?o.constructor:null}, 136 "string":function(){return String}, 137 "undefined":function(){return null} 138 }, 139 $$ = function(m){ 140 function $(c,t){t=c[m];delete c[m];try{e(c)}catch(z){c[m]=t;return 1}}; 141 return $(Array)&&$(Object) 142 }; 143 try{rc=new RegExp('^("(\\\\.|[^"\\\\\\n\\r])*?"|[,:{}\\[\\]0-9.\\-+Eaeflnr-u \\n\\r\\t])+?$')} 144 catch(z){rc=/^(true|false|null|\[.*\]|\{.*\}|".*"|\d+|\d+\.\d+)$/} 145 };
至此,已经可以轻松搞定JSON时间处理的麻烦。不过这里有一点点不完美的地方,要求.NET端的时间使用UTC时间,总的来说这也不是什么大的缺陷,可以接受。我的理由是在多时区时就应当在服务端使用UTC时间。