這次帶給大家Json操作日期格式,Json操作日期格式的注意事項有哪些,以下就是實戰案例,一起來看一下。
開發中有時候需要從伺服器端返回json格式的數據,在後台程式碼中如果有DateTime類型的數據使用系統自帶的工具類序列化後將得到一個很長的數字表示日期數據,如下所示:
//设置服务器响应的结果为纯文本格式 context.Response.ContentType = "text/plain"; //学生对象集合 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(); //序列化学生集合对象得到json字符 string studentsJson=jss.Serialize(students); //将字符串响应到客户端 context.Response.Write(studentsJson); context.Response.End();
運行結果是:
其中Tom所對應生日「2014-01-31」變成了1391141532000 ,這其實是1970 年1 月1 日至今的毫秒數;1391141532000/1000/60/60/24/365=44.11年,44 1970=2014年,依此方法可以得出年時分時分和毫秒。這種格式是一種可行的表示形式但不是一般人可以看懂的友善格式,怎麼讓這個格式改變?
解決方法:
#方法1:在伺服器端將日期格式使用Select方法或LINQ表達式轉換後發到客戶端:
using System; using System.Collections.Generic; using System.Web; using System.Web.Script.Serialization; namespace JsonDate1 { using System.Linq; /// <summary> /// 学生类,测试用 /// </summary> public class Student { /// <summary> /// 姓名 /// </summary> public String Name { get; set; } /// <summary> /// 生日 /// </summary> public DateTime Birthday { get; set; } } /// <summary> /// 返回学生集合的json字符 /// </summary> public class GetJson : IHttpHandler { public void ProcessRequest(HttpContext context) { //设置服务器响应的结果为纯文本格式 context.Response.ContentType = "text/plain"; //学生对象集合 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方法重新投影对象集合将Birthday属性转换成一个新的属性 //注意属性变化后要重新命名,并立即执行 var studentSet = students.Select ( p => new { p.Name, Birthday = p.Birthday.ToString("yyyy-mm-dd") } ).ToList(); //javascript序列化器 JavaScriptSerializer jss = new JavaScriptSerializer(); //序列化学生集合对象得到json字符 string studentsJson = jss.Serialize(studentSet); //将字符串响应到客户端 context.Response.Write(studentsJson); context.Response.End(); } public bool IsReusable { get { return false; } } } }
Select方法重新投影物件集合將Birthday屬性轉換成一個新的屬性,注意屬性變更後要重新命名,屬性名稱可以相同;這裡可以使用select方法也可以使用LINQ查詢表達式,也可以選擇別的方式達到相同的目的;這種辦法可以將集合中客戶端不用的屬性剔除,達到簡單優化效能的目的。
運行結果:
這時候的日期格式就已經變成友善格式了,不過在javascript中這只是一個字串。
方法二:
在javascript中將"Birthday":"\/Date(1391141532000)\/"中的字串轉換成javascript中的日期對象,可以將Birthday這個Key所對應的Value中的非數字字元以替換的方式刪除,到到一個數字1391141532000,然後實例化一個Date對象,將1391141532000毫秒作為參數,得到一個javascript中的日期對象,代碼如下:
<!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)删除 //并把得到的毫秒数转换成数字类型 var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, "")); //实例化一个新的日期格式,使用1970 年 1 月 1 日至今的毫秒数为参数 var birthday = new Date(birthdayMilliseconds); $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents"); ; }); }); }); </script> </head> <body> <h2>json日期格式处理</h2> <ul id="ulStudents"> </ul> </body> </html>
運行結果:
上的使用正規/\D/igm達到替換所有非數字的目的,\D表示非數字,igm是參數,分別表示忽略(ignore)大小寫;多次、全域(global)替換;多行替換(multi-line);有些時候還會出現86的情況,只需要變換正規同樣可以達到目的。另外如果專案中反覆出現這種需要處理日期格式的問題,可以擴充一個javascript方法,程式碼如下:
$(function () { $.getJSON("getJson.ashx", function (students) { $.each(students, function (index, obj) { $("<li/>").html(obj.Name).appendTo("#ulStudents"); //使用正则表达式将生日属性中的非数字(\D)删除 //并把得到的毫秒数转换成数字类型 var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, "")); //实例化一个新的日期格式,使用1970 年 1 月 1 日至今的毫秒数为参数 var birthday = new Date(birthdayMilliseconds); $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents"); $("<li/>").html(obj.Birthday.toDate()).appendTo("#ulStudents"); }); }); }); //在String对象中扩展一个toDate方法,可以根据要求完善 String.prototype.toDate = function () { var dateMilliseconds; if (isNaN(this)) { //使用正则表达式将日期属性中的非数字(\D)删除 dateMilliseconds =this.replace(/\D/igm, ""); } else { dateMilliseconds=this; } //实例化一个新的日期格式,使用1970 年 1 月 1 日至今的毫秒数为参数 return new Date(parseInt(dateMilliseconds)); };
上面擴充的方法toDate不一定合理,也不夠強大,可以根據需要修改。
方法三:
可以選擇一些第三方的json工具類,其中不乏有一些已經對日期格式問題已處理好了的,常見的json序列化與反序列化工具庫有:
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的工具類別作範例,程式碼如下:
using System; using System.Collections.Generic; using System.Web; using LitJson; namespace JsonDate2 { using System.Linq; /// <summary> /// 学生类,测试用 /// </summary> public class Student { /// <summary> /// 姓名 /// </summary> public String Name { get; set; } /// <summary> /// 生日 /// </summary> public DateTime Birthday { get; set; } } /// <summary> /// 返回学生集合的json字符 /// </summary> public class GetJson : IHttpHandler { public void ProcessRequest(HttpContext context) { //设置服务器响应的结果为纯文本格式 context.Response.ContentType = "text/plain"; //学生对象集合 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")} }; //序列化学生集合对象得到json字符 string studentsJson = JsonMapper.ToJson(students); //将字符串响应到客户端 context.Response.Write(studentsJson); context.Response.End(); } public bool IsReusable { get { return false; } } } }
運行結果如下:
#這時候的日期格式就基本上正確了,只要在javascript中直接實例化日期就好了,
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());
方法四:
這點文字發到博客上有網友提出了他們寶貴的意見,我並沒有考慮在MVC中的情況,其實MVC中也可以使用handler,所以區別不是很大了,但MVC中有專門針對伺服器回應為JSON的Action,程式碼如下:
using System; using System.Web.Mvc; namespace JSONDateMVC.Controllers { public class HomeController : Controller { public JsonResult GetJson1() { //序列化当前日期与时间对象,并允许客户端Get请求 return Json(DateTime.Now, JsonRequestBehavior.AllowGet); } } }
運行結果:
下载一个内容为Application/json的文件,文件名为GetJson1,内容是"\/Date(1391418272884)\/"
从上面的情况看来MVC中序列化时并未对日期格式特别处理,我们可以反编译看源码:
Return调用的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类ActionResult类的子类,ExecuteResult方法:
从上面的代码中不难看出微软的JsonResult类仍然是使用了JavaScriptSerializer,所以返回的结果与方法一未处理时是一样的,要解决这个问题我们可以派生出一个新的类,重写ExecuteResult方法,使用Json.net来完成序列化工作,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) { //转换System.DateTime的日期格式到 ISO 8601日期格式 //ISO 8601 (如2008-04-12T12:53Z) IsoDateTimeConverter isoDateTimeConverter=new IsoDateTimeConverter(); //设置日期格式 isoDateTimeConverter.DateTimeFormat = DateTimeFormat; //序列化 String jsonResult = JsonConvert.SerializeObject(this.Data,isoDateTimeConverter); //相应结果 base2.Write(jsonResult); } } } }
使用上面的JsonResultPro Action类型的代码如下:
public JsonResultPro GetJson2() { //序列化当前日期与时间对象,并允许客户端Get请求,注意H是大写 return new JsonResultPro(DateTime.Now,"yyyy-MM-dd HH:mm"); }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
以上是Json操作日期格式的詳細內容。更多資訊請關注PHP中文網其他相關文章!