这次给大家带来Json操作日期格式,Json操作日期格式的注意事项有哪些,下面就是实战案例,一起来看一下。
开发中有时候需要从服务器端返回json格式的数据,在后台代码中如果有DateTime类型的数据使用系统自带的工具类序列化后将得到一个很长的数字表示日期数据,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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" )}
};
JavaScriptSerializer jss= new JavaScriptSerializer();
string studentsJson=jss.Serialize(students);
context.Response.Write(studentsJson);
context.Response. End ();
|
登录后复制
运行结果是:
![](https://img.php.cn/upload/article/000/061/021/a908337bd7a4d045bd1b6c33fa44e372-0.jpg)
其中Tom所对应生日“2014-01-31”变成了1391141532000,这其实是1970 年 1 月 1 日至今的毫秒数;1391141532000/1000/60/60/24/365=44.11年,44+1970=2014年,按这种方法可以得出年月日时分秒和毫秒。这种格式是一种可行的表示形式但不是普通人可以看懂的友好格式,怎么让这个格式变化?
解决办法:
方法1:在服务器端将日期格式使用Select方法或LINQ表达式转换后发到客户端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Script.Serialization;
namespace JsonDate1
{
using System.Linq;
public class Student
{
public String Name { get; set; }
public DateTime Birthday { get; set; }
}
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" )}
};
var studentSet =
students.Select
(
p => new { p.Name, Birthday = p.Birthday.ToString( "yyyy-mm-dd" ) }
).ToList();
JavaScriptSerializer jss = new JavaScriptSerializer();
string studentsJson = jss.Serialize(studentSet);
context.Response.Write(studentsJson);
context.Response. End ();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
|
登录后复制
Select方法重新投影对象集合将Birthday属性转换成一个新的属性,注意属性变化后要重新命名,属性名可以相同;这里可以使用select方法也可以使用LINQ查询表达式,也可以选择别的方式达到相同的目的;这种办法可以将集合中客户端不用的属性剔除,达到简单优化性能的目的。
运行结果:
![](https://img.php.cn/upload/article/000/061/021/6b5dbbf0d3cb2259b6e5d18bcffd744e-1.png)
这时候的日期格式就已经变成友好格式了,不过在javascript中这只是一个字符串。
方法二:
在javascript中将"Birthday":"\/Date(1391141532000)\/"中的字符串转换成javascript中的日期对象,可以将Birthday这个Key所对应的Value中的非数字字符以替换的方式删除,到到一个数字1391141532000,然后实例化一个Date对象,将1391141532000毫秒作为参数,得到一个javascript中的日期对象,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <!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" );
var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, "" ));
var birthday = new Date (birthdayMilliseconds);
$( "<li/>" ).html(birthday.toLocaleString()).appendTo( "#ulStudents" ); ;
});
});
});
</script>
</head>
<body>
<h2>json日期格式处理</h2>
<ul id= "ulStudents" >
</ul>
</body>
</html>
|
登录后复制
运行结果:
![](https://img.php.cn/upload/article/000/061/021/6b5dbbf0d3cb2259b6e5d18bcffd744e-2.jpg)
上的使用正则/\D/igm达到替换所有非数字的目的,\D表示非数字,igm是参数,分别表示忽视(ignore)大小写;多次、全局(global)替换;多行替换(multi-line);有一些时候还会出现+86的情况,只需要变换正则同样可以达到目的。另外如果项目中反复出现这种需要处理日期格式的问题,可以扩展一个javascript方法,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | $( function () {
$.getJSON( "getJson.ashx" , function (students) {
$.each(students, function (index, obj) {
$( "<li/>" ).html(obj.Name).appendTo( "#ulStudents" );
var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, "" ));
var birthday = new Date (birthdayMilliseconds);
$( "<li/>" ).html(birthday.toLocaleString()).appendTo( "#ulStudents" );
$( "<li/>" ).html(obj.Birthday.toDate()).appendTo( "#ulStudents" );
});
});
});
String.prototype.toDate = function () {
var dateMilliseconds;
if (isNaN(this)) {
dateMilliseconds =this.replace(/\D/igm, "" );
} else {
dateMilliseconds=this;
}
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的工具类作示例,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | using System;
using System.Collections.Generic;
using System.Web;
using LitJson;
namespace JsonDate2
{
using System.Linq;
public class Student
{
public String Name { get; set; }
public DateTime Birthday { get; set; }
}
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" )}
};
string studentsJson = JsonMapper.ToJson(students);
context.Response.Write(studentsJson);
context.Response. End ();
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
|
登录后复制
运行结果如下:
![](https://img.php.cn/upload/article/000/061/021/6b5dbbf0d3cb2259b6e5d18bcffd744e-3.jpg)
这时候的日期格式就基本正确了,只要在javascript中直接实例化日期就好了,
1 2 | var date = new Date ( "01/31/2014 12:12:12" );
alert( date .toLocaleString());
|
登录后复制
客户端的代码如下:
1 2 3 4 5 6 7 8 9 10 11 | $( 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,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System;
using System.Web.Mvc;
namespace JSONDateMVC.Controllers
{
public class HomeController : Controller
{
public JsonResult GetJson1()
{
return Json(DateTime.Now, JsonRequestBehavior.AllowGet);
}
}
}
|
登录后复制
运行结果:
下载一个内容为Application/json的文件,文件名为GetJson1,内容是"\/Date(1391418272884)\/"
从上面的情况看来MVC中序列化时并未对日期格式特别处理,我们可以反编译看源码:
Return调用的Json方法:
1 2 3 4 5 6 7 8 9 | 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方法:
![](https://img.php.cn/upload/article/000/061/021/b026b87a48fc8cc1de80958dd03db7a5-4.png)
从上面的代码中不难看出微软的JsonResult类仍然是使用了JavaScriptSerializer,所以返回的结果与方法一未处理时是一样的,要解决这个问题我们可以派生出一个新的类,重写ExecuteResult方法,使用Json.net来完成序列化工作,JsonResultPro.cs文件的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | 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;
}
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)
{
IsoDateTimeConverter isoDateTimeConverter= new IsoDateTimeConverter();
isoDateTimeConverter.DateTimeFormat = DateTimeFormat;
String jsonResult = JsonConvert.SerializeObject(this.Data,isoDateTimeConverter);
base2.Write(jsonResult);
}
}
}
}
|
登录后复制
使用上面的JsonResultPro Action类型的代码如下:
1 2 3 4 5 | public JsonResultPro GetJson2()
{
return new JsonResultPro(DateTime.Now, "yyyy-MM-dd HH:mm" );
}
|
登录后复制
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
jsonp+json实现AJAX跨域请求
Jsonp怎样才能解决ajax跨域
以上是Json操作日期格式的详细内容。更多信息请关注PHP中文网其他相关文章!