Json日期格式问题的四种解决方法(超详细)

 更新时间:2021年9月22日 10:04  点击:1383

开发中有时候需要从服务器端返回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");
 }

运行结果:

"2014-02-03 18:10"

这样就可以完全按自己的意思来设置日期格式了,但需要注意日期格式如平时的Format是有区别的,如这里表示时间的H如果大写表示24小时制,如果小写表示12小时制。另外还有几个问题要问大家:

1、通过Reflector反编译得到的代码中有很多变化,如属性会变成get_Request()方法的形式,不知道大家有没有更好的方法。

2、在反编译得到的代码中使用到了资源文件MvcResources.JsonRequest_GetNotAllowed,怎么在重写时也可以使用?

以上所述是小编给大家介绍的Json日期格式问题的四种解决方法小结(超详细),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对猪先飞网站的支持!

[!--infotagslink--]

相关文章

  • gin 获取post请求的json body操作

    这篇文章主要介绍了gin 获取post请求的json body操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-15
  • 详解Mysql中的JSON系列操作函数

    新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
  • Json格式详解

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成...2021-11-05
  • C#使用Http Post方式传递Json数据字符串调用Web Service

    这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • js遍历json的key和value的实例

    下面小编就为大家带来一篇js遍历json的key和value的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-01-26
  • JS日期加减,日期运算代码

    一、日期减去天数等于第二个日期function cc(dd,dadd){//可以加上错误处理var a = new Date(dd)a = a.valueOf()a = a - dadd * 24 * 60 * 60 * 1000a = new Date(a)alert(a.getFullYear() + "年" + (a.getMonth() +...2015-11-08
  • 详解.NET Core 3.0 里新的JSON API

    这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • php计算两个日期相差天数的方法

    本文实例讲述了php计算两个日期相差天数的方法。...2015-03-15
  • PostgreSQL 字符串处理与日期处理操作

    这篇文章主要介绍了PostgreSQL 字符串处理与日期处理操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-01
  • vue开发之moment的介绍与使用

    moment是一款多语言支持的日期处理类库, 在vue中如何使用呢?这篇文章主要给大家介绍了关于vue之moment使用的相关资料,需要的朋友可以参考下...2021-05-13
  • ASP.NET Core根据环境变量支持多个 appsettings.json配置文件

    这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
  • 非常全面的php日期时间运算汇总

    实例讲解之前,先来介绍几个核心函数: mktime 函数 mktime() 函数返回一个日期的 Unix 时间戳。 参数总是表示 GMT 日期,因此 is_dst 对结果没有影响。 参数可以从右到左依次空着,空着的参数会被设为相应的当前 GMT 值。...2015-11-08
  • 基于Vue+Openlayer实现动态加载geojson的方法

    本文通过实例代码给大家介绍基于Vue+Openlayer实现动态加载geojson的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-09-01
  • C#实现将字符串转换成日期格式的方法

    这篇文章主要介绍了C#实现将字符串转换成日期格式的方法,涉及C#操作时间及字符串的相关技巧,非常简单实用,需要的朋友可以参考下...2020-06-25
  • php实例分享之html转为rtf格式

    核心代码: 复制代码 代码如下:<!--?php$html2RTFCom = new COM("HTML2RTF.Converter");$html2RTFCom--->PreserveImages = true;$html2RTFCom->PageNumbers = 1;$html2RTFCom->PageNumbersAlignH = 1;$html2RTFCom->Pa...2014-06-07
  • jquery对Json的各种遍历方法总结(必看篇)

    下面就为大家带来一篇jquery对Json的各种遍历方法总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-02
  • 解决HttpPost+json请求---服务器中文乱码及其他问题

    这篇文章主要介绍了解决HttpPost+json请求---服务器中文乱码及其他问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22
  • php根据日期或时间戳获取星座信息和生肖等信息

    分享一个利用php根据日期或时间戳获取相应的干支纪年,生肖和星座信息的函数方法,具体函数代码以及使用方法如下: /** 判断干支、生肖和星座 */ function birthext($birth){ if(strstr($birth,'-')===false&&strlen($bi...2015-10-21
  • 替换json对象中的key最佳方案

    本文给大家介绍如何替换json对象中的key,通过实例代码给大家介绍key的替换方法,代码也很简单,需要的朋友参考下吧...2021-06-02
  • Pycharm 设置默认解释器路径和编码格式的操作

    这篇文章主要介绍了Pycharm 设置默认解释器路径和编码格式的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-05