您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關(guān)Json日期格式問(wèn)題的示例分析的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。
開(kāi)發(fā)中有時(shí)候需要從服務(wù)器端返回json格式的數(shù)據(jù),在后臺(tái)代碼中如果有DateTime類(lèi)型的數(shù)據(jù)使用系統(tǒng)自帶的工具類(lèi)序列化后將得到一個(gè)很長(zhǎng)的數(shù)字表示日期數(shù)據(jù),如下所示:
//設(shè)置服務(wù)器響應(yīng)的結(jié)果為純文本格式 context.Response.ContentType = "text/plain"; //學(xué)生對(duì)象集合 List<Student> students = new List<Student> { new Student(){Name ="Tom", Birthday =Convert.ToDateTime("2014-01-31 12:12:12")}, new Student(){Name ="Rose", Birthday =Convert.ToDateTime("2014-01-10 11:12:12")}, new Student(){Name ="Mark", Birthday =Convert.ToDateTime("2014-01-09 10:12:12")} }; //javascript序列化器 JavaScriptSerializer jss=new JavaScriptSerializer(); //序列化學(xué)生集合對(duì)象得到j(luò)son字符 string studentsJson=jss.Serialize(students); //將字符串響應(yīng)到客戶端 context.Response.Write(studentsJson); context.Response.End();
運(yùn)行結(jié)果是:
其中Tom所對(duì)應(yīng)生日“2014-01-31”變成了1391141532000,這其實(shí)是1970 年 1 月 1 日至今的毫秒數(shù);1391141532000/1000/60/60/24/365=44.11年,44+1970=2014年,按這種方法可以得出年月日時(shí)分秒和毫秒。這種格式是一種可行的表示形式但不是普通人可以看懂的友好格式,怎么讓這個(gè)格式變化?
解決辦法:
方法1:在服務(wù)器端將日期格式使用Select方法或LINQ表達(dá)式轉(zhuǎn)換后發(fā)到客戶端:
using System; using System.Collections.Generic; using System.Web; using System.Web.Script.Serialization; namespace JsonDate1 { using System.Linq; /// <summary> /// 學(xué)生類(lèi),測(cè)試用 /// </summary> public class Student { /// <summary> /// 姓名 /// </summary> public String Name { get; set; } /// <summary> /// 生日 /// </summary> public DateTime Birthday { get; set; } } /// <summary> /// 返回學(xué)生集合的json字符 /// </summary> public class GetJson : IHttpHandler { public void ProcessRequest(HttpContext context) { //設(shè)置服務(wù)器響應(yīng)的結(jié)果為純文本格式 context.Response.ContentType = "text/plain"; //學(xué)生對(duì)象集合 List<Student> students = new List<Student> { new Student(){Name ="Tom",Birthday =Convert.ToDateTime("2014-01-31 12:12:12")}, new Student(){Name ="Rose",Birthday =Convert.ToDateTime("2014-01-10 11:12:12")}, new Student(){Name ="Mark",Birthday =Convert.ToDateTime("2014-01-09 10:12:12")} }; //使用Select方法重新投影對(duì)象集合將Birthday屬性轉(zhuǎn)換成一個(gè)新的屬性 //注意屬性變化后要重新命名,并立即執(zhí)行 var studentSet = students.Select ( p => new { p.Name, Birthday = p.Birthday.ToString("yyyy-mm-dd") } ).ToList(); //javascript序列化器 JavaScriptSerializer jss = new JavaScriptSerializer(); //序列化學(xué)生集合對(duì)象得到j(luò)son字符 string studentsJson = jss.Serialize(studentSet); //將字符串響應(yīng)到客戶端 context.Response.Write(studentsJson); context.Response.End(); } public bool IsReusable { get { return false; } } } }
Select方法重新投影對(duì)象集合將Birthday屬性轉(zhuǎn)換成一個(gè)新的屬性,注意屬性變化后要重新命名,屬性名可以相同;這里可以使用select方法也可以使用LINQ查詢(xún)表達(dá)式,也可以選擇別的方式達(dá)到相同的目的;這種辦法可以將集合中客戶端不用的屬性剔除,達(dá)到簡(jiǎn)單優(yōu)化性能的目的。
運(yùn)行結(jié)果:
這時(shí)候的日期格式就已經(jīng)變成友好格式了,不過(guò)在javascript中這只是一個(gè)字符串。
方法二:
在javascript中將"Birthday":"\/Date(1391141532000)\/"中的字符串轉(zhuǎn)換成javascript中的日期對(duì)象,可以將Birthday這個(gè)Key所對(duì)應(yīng)的Value中的非數(shù)字字符以替換的方式刪除,到到一個(gè)數(shù)字1391141532000,然后實(shí)例化一個(gè)Date對(duì)象,將1391141532000毫秒作為參數(shù),得到一個(gè)javascript中的日期對(duì)象,代碼如下:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>json日期格式處理</title> <script src="Scripts/jquery-1.10.2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function() { $.getJSON("getJson.ashx", function (students) { $.each(students, function (index, obj) { $("<li/>").html(obj.Name).appendTo("#ulStudents"); //使用正則表達(dá)式將生日屬性中的非數(shù)字(\D)刪除 //并把得到的毫秒數(shù)轉(zhuǎn)換成數(shù)字類(lèi)型 var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, "")); //實(shí)例化一個(gè)新的日期格式,使用1970 年 1 月 1 日至今的毫秒數(shù)為參數(shù) var birthday = new Date(birthdayMilliseconds); $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents"); ; }); }); }); </script> </head> <body> <h3>json日期格式處理</h3> <ul id="ulStudents"> </ul> </body> </html>
運(yùn)行結(jié)果:
上的使用正則/\D/igm達(dá)到替換所有非數(shù)字的目的,\D表示非數(shù)字,igm是參數(shù),分別表示忽視(ignore)大小寫(xiě);多次、全局(global)替換;多行替換(multi-line);有一些時(shí)候還會(huì)出現(xiàn)+86的情況,只需要變換正則同樣可以達(dá)到目的。另外如果項(xiàng)目中反復(fù)出現(xiàn)這種需要處理日期格式的問(wèn)題,可以擴(kuò)展一個(gè)javascript方法,代碼如下:
$(function () { $.getJSON("getJson.ashx", function (students) { $.each(students, function (index, obj) { $("<li/>").html(obj.Name).appendTo("#ulStudents"); //使用正則表達(dá)式將生日屬性中的非數(shù)字(\D)刪除 //并把得到的毫秒數(shù)轉(zhuǎn)換成數(shù)字類(lèi)型 var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, "")); //實(shí)例化一個(gè)新的日期格式,使用1970 年 1 月 1 日至今的毫秒數(shù)為參數(shù) var birthday = new Date(birthdayMilliseconds); $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents"); $("<li/>").html(obj.Birthday.toDate()).appendTo("#ulStudents"); }); }); }); //在String對(duì)象中擴(kuò)展一個(gè)toDate方法,可以根據(jù)要求完善 String.prototype.toDate = function () { var dateMilliseconds; if (isNaN(this)) { //使用正則表達(dá)式將日期屬性中的非數(shù)字(\D)刪除 dateMilliseconds =this.replace(/\D/igm, ""); } else { dateMilliseconds=this; } //實(shí)例化一個(gè)新的日期格式,使用1970 年 1 月 1 日至今的毫秒數(shù)為參數(shù) return new Date(parseInt(dateMilliseconds)); };
上面擴(kuò)展的方法toDate不一定合理,也不夠強(qiáng)大,可以根據(jù)需要修改。
方法三:
可以選擇一些第三方的json工具類(lèi),其中不乏有一些已經(jīng)對(duì)日期格式問(wèn)題已處理好了的,常見(jiàn)的json序列化與反序列化工具庫(kù)有:
1.fastJSON.
2.JSON_checker.
3.Jayrock.
4.Json.NET - LINQ to JSON.
5.LitJSON.
6.JSON for .NET.
7.JsonFx.
8.JSONSharp.
9.JsonExSerializer.
10.fluent-json
11.Manatee Json
這里以litjson為序列化與反序列化json的工具類(lèi)作示例,代碼如下:
using System; using System.Collections.Generic; using System.Web; using LitJson; namespace JsonDate2 { using System.Linq; /// <summary> /// 學(xué)生類(lèi),測(cè)試用 /// </summary> public class Student { /// <summary> /// 姓名 /// </summary> public String Name { get; set; } /// <summary> /// 生日 /// </summary> public DateTime Birthday { get; set; } } /// <summary> /// 返回學(xué)生集合的json字符 /// </summary> public class GetJson : IHttpHandler { public void ProcessRequest(HttpContext context) { //設(shè)置服務(wù)器響應(yīng)的結(jié)果為純文本格式 context.Response.ContentType = "text/plain"; //學(xué)生對(duì)象集合 List<Student> students = new List<Student> { new Student(){Name ="Tom",Birthday =Convert.ToDateTime("2014-01-31 12:12:12")}, new Student(){Name ="Rose",Birthday =Convert.ToDateTime("2014-01-10 11:12:12")}, new Student(){Name ="Mark",Birthday =Convert.ToDateTime("2014-01-09 10:12:12")} }; //序列化學(xué)生集合對(duì)象得到j(luò)son字符 string studentsJson = JsonMapper.ToJson(students); //將字符串響應(yīng)到客戶端 context.Response.Write(studentsJson); context.Response.End(); } public bool IsReusable { get { return false; } } } }
運(yùn)行結(jié)果如下:
這時(shí)候的日期格式就基本正確了,只要在javascript中直接實(shí)例化日期就好了,
var date = new Date("01/31/2014 12:12:12"); alert(date.toLocaleString());
客戶端的代碼如下:
$(function () { $.getJSON("GetJson2.ashx", function (students) { $.each(students, function (index, obj) { $("<li/>").html(obj.Name).appendTo("#ulStudents"); var birthday = new Date(obj.Birthday); $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents"); }); }); }); var date = new Date("01/31/2014 12:12:12"); alert(date.toLocaleString());
方法四:
這點(diǎn)文字發(fā)到博客上有網(wǎng)友提出了他們寶貴的意見(jiàn),我并沒(méi)有考慮在MVC中的情況,其實(shí)MVC中也可以使用handler,所以區(qū)別不是很大了,但MVC中有專(zhuān)門(mén)針對(duì)服務(wù)器響應(yīng)為JSON的Action,代碼如下:
using System; using System.Web.Mvc; namespace JSONDateMVC.Controllers { public class HomeController : Controller { public JsonResult GetJson1() { //序列化當(dāng)前日期與時(shí)間對(duì)象,并允許客戶端Get請(qǐng)求 return Json(DateTime.Now, JsonRequestBehavior.AllowGet); } } }
運(yùn)行結(jié)果:
下載一個(gè)內(nèi)容為Application/json的文件,文件名為GetJson1,內(nèi)容是"\/Date(1391418272884)\/"
從上面的情況看來(lái)MVC中序列化時(shí)并未對(duì)日期格式特別處理,我們可以反編譯看源碼:
Return調(diào)用的Json方法:
protected internal JsonResult Json(object data, JsonRequestBehavior behavior) { return this.Json(data, null, null, behavior); } this.Json方法 protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior) { return new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior }; }
JsonResult類(lèi)ActionResult類(lèi)的子類(lèi),ExecuteResult方法:
從上面的代碼中不難看出微軟的JsonResult類(lèi)仍然是使用了JavaScriptSerializer,所以返回的結(jié)果與方法一未處理時(shí)是一樣的,要解決這個(gè)問(wèn)題我們可以派生出一個(gè)新的類(lèi),重寫(xiě)ExecuteResult方法,使用Json.net來(lái)完成序列化工作,JsonResultPro.cs文件的代碼如下:
namespace JSONDateMVC.Common { using System; using System.Web; using System.Web.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Converters; public class JsonResultPro : JsonResult { public JsonResultPro(){} public JsonResultPro(object data, JsonRequestBehavior behavior) { base.Data = data; base.JsonRequestBehavior = behavior; this.DateTimeFormat = "yyyy-MM-dd hh:mm:ss"; } public JsonResultPro(object data, String dateTimeFormat) { base.Data = data; base.JsonRequestBehavior = JsonRequestBehavior.AllowGet; this.DateTimeFormat = dateTimeFormat; } /// <summary> /// 日期格式 /// </summary> public string DateTimeFormat{ get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if ((this.JsonRequestBehavior == JsonRequestBehavior.DenyGet) && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("MvcResources.JsonRequest_GetNotAllowed"); } HttpResponseBase base2 = context.HttpContext.Response; if (!string.IsNullOrEmpty(this.ContentType)) { base2.ContentType = this.ContentType; } else { base2.ContentType = "application/json"; } if (this.ContentEncoding != null) { base2.ContentEncoding = this.ContentEncoding; } if (this.Data != null) { //轉(zhuǎn)換System.DateTime的日期格式到 ISO 8601日期格式 //ISO 8601 (如2008-04-12T12:53Z) IsoDateTimeConverter isoDateTimeConverter=new IsoDateTimeConverter(); //設(shè)置日期格式 isoDateTimeConverter.DateTimeFormat = DateTimeFormat; //序列化 String jsonResult = JsonConvert.SerializeObject(this.Data,isoDateTimeConverter); //相應(yīng)結(jié)果 base2.Write(jsonResult); } } } }
使用上面的JsonResultPro Action類(lèi)型的代碼如下:
public JsonResultPro GetJson2() { //序列化當(dāng)前日期與時(shí)間對(duì)象,并允許客戶端Get請(qǐng)求,注意H是大寫(xiě) return new JsonResultPro(DateTime.Now,"yyyy-MM-dd HH:mm"); }
運(yùn)行結(jié)果:
"2014-02-03 18:10"
感謝各位的閱讀!關(guān)于“Json日期格式問(wèn)題的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。