Four ways to troubleshoot JSON date format problems

Source: Internet
Author: User
Tags iso 8601 iso 8601 date iso 8601 date format
This article mainly introduces the JSON date format problem of four kinds of solutions, very good, with reference value, the need for friends can refer to the following





In development, it is sometimes necessary to return JSON-formatted data from the server side, and in the background code, if a datetime type of data is serialized using the system's own tool class, a long numeric representation of the date data is given, as follows:


// Set the server response result to plain text format
  context.Response.ContentType = "text / plain";
  // student object collection
  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 serializer
  JavascriptSerializer jss = new JavascriptSerializer ();
  // Serialize the student collection object to get json characters
  string studentsJson = jss.Serialize (students);
  // response the string to the client
  context.Response.Write (studentsJson);
  context.Response.End (); 


The operating result is:






Where Tom's corresponding birthday "2014-01-31" became 1391141532000, which is actually the number of milliseconds since January 1, 1970; 1391141532000/1000/60/60/24/365=44.11 years, 44+1970= In 2014, this method can be used to derive the day of the month, minutes and milliseconds. This format is a workable representation but not a friendly format that ordinary people can understand, how to make this format change?



Workaround:



Method 1: Convert the date format to the client by using the Select method or the LINQ expression on the server side:


using System;
using System.Collections.Generic;
using System.Web;
using System.Web.script.Serialization;
namespace JsonDate1
{
 using System.Linq;
 /// <summary>
 /// Student class, for testing
 /// </ summary>
 public class Student
 {
 /// <summary>
 /// name
 /// </ summary>
 public String Name {get; set;}
 /// <summary>
 /// birthday
 /// </ summary>
 public DateTime Birthday {get; set;}
 }
 /// <summary>
 /// return the json character of the student collection
 /// </ summary>
 public class GetJson: IHttpHandler
 {
 public void ProcessRequest (HttpContext context)
 {
 // Set the server response result to plain text format
 context.Response.ContentType = "text / plain";
 // student object collection
 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")}
 };
 // Use the Select method to reproject the collection of objects to transform the Birthday property into a new property
 // Note that the property should be renamed after the property changes, and executed immediately
 var studentSet =
 students.Select
 (
 p => new {p.Name, Birthday = p.Birthday.ToString ("yyyy-mm-dd")}
 ) .ToList ();
 // javascript serializer
 JavascriptSerializer jss = new JavascriptSerializer ();
 // Serialize the student collection object to get json characters
 string studentsJson = jss.Serialize (studentSet);
 // response the string to the client
 context.Response.Write (studentsJson);
 context.Response.End ();
 }
 public bool IsReusable
 {
 get
 {
 return false;
 }
 }
 }
}

The Select method re-projects the collection of objects to convert the Birthday property to a new property, note that the property name can be the same after the property changes, you can use the Select method, or you can use a LINQ query expression or choose another way to achieve the same purpose This method can be used to eliminate the properties of the client in the collection, to achieve the purpose of simple optimization performance.



Operation Result:






The date format is now a friendly format, but in JavaScript it's just a string.



Method Two:



Converts a string from "Birthday": "\/date (1391141532000) \ \" In JavaScript to a Date object in JavaScript, You can delete the non-numeric word utilises substitution in the value corresponding to the birthday key to a number 1391141532000, then instantiate a Date object with 1391141532000 milliseconds as the argument. Get a Date object in JavaScript with the following code:



<! DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
 <title> json date format processing </ 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");
 // Use regular expressions to delete non-numbers (\ D) in birthday attributes
 // and convert the obtained milliseconds into a numeric type
 var birthdayMilliseconds = parseInt (obj.Birthday.replace (/ \ D / igm, ""));
 // Instantiate a new date format, using the number of milliseconds from January 1, 1970 to the present
 var birthday = new Date (birthdayMilliseconds);
 $ ("<li />"). html (birthday.toLocaleString ()). appendTo ("# ulStudents");;
 });
 });
 });
 </ script>
</ head>
<body>
 <h2> json date format processing </ h2>
 <ul id = "ulStudents">
 </ ul>
</ body>
</ html>
operation result:

Use regular / \ D / igm to replace all non-numeric, \ D means non-numeric, igm is a parameter, which means ignore case respectively; multiple global replacements; multi-line replacement (multi -line); There are times when +86 will occur, and you only need to change the regular to achieve the same goal. In addition, if this kind of problem that needs to deal with date format repeatedly occurs in the project, you can extend a javascript method, the code is as follows:

$ (function () {
 $ .getJSON ("getJson.ashx", function (students) {
 $ .each (students, function (index, obj) {
 $ ("<li />"). html (obj.Name) .appendTo ("# ulStudents");
 // Use regular expressions to delete non-numbers (\ D) in birthday attributes
 // and convert the obtained milliseconds into a numeric type
 var birthdayMilliseconds = parseInt (obj.Birthday.replace (/ \ D / igm, ""));
 // Instantiate a new date format, using the number of milliseconds from January 1, 1970 to the present
 var birthday = new Date (birthdayMilliseconds);
 $ ("<li />"). html (birthday.toLocaleString ()). appendTo ("# ulStudents");
 $ ("<li />"). html (obj.Birthday.toDate ()). appendTo ("# ulStudents");
 });
 });
 });
 // Extend a toDate method in the String object, which can be improved according to requirements
 String.prototype.toDate = function () {
 var dateMilliseconds;
 if (isNaN (this)) {
 // Remove non-numeric (\ D) in date attribute using regular expression
 dateMilliseconds = this.replace (/ \ D / igm, "");
 } else {
 dateMilliseconds = this;
 }
 // Instantiate a new date format, using the number of milliseconds from January 1, 1970 to the present
 return new Date (parseInt (dateMilliseconds));
 };
The extended method toDate above is not necessarily reasonable and not powerful enough, and can be modified as needed.

Method three:

You can choose some third-party json tool classes, some of which have already dealt with date format issues. Common json serialization and deserialization tool libraries are:

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

Here we take litjson as an example for serializing and deserializing json tools. The code is as follows:

using System;
using System.Collections.Generic;
using System.Web;
using LitJson;
namespace JsonDate2
{
 using System.Linq;
 /// <summary>
 /// Student class, for testing
 /// </ summary>
 public class Student
 {
 /// <summary>
 /// name
 /// </ summary>
 public String Name {get; set;}
 /// <summary>
 /// birthday
 /// </ summary>
 public DateTime Birthday {get; set;}
 }
 /// <summary>
 /// return the json character of the student collection
 /// </ summary>
 public class GetJson: IHttpHandler
 {
 public void ProcessRequest (HttpContext context)
 {
 // Set the server response result to plain text format
 context.Response.ContentType = "text / plain";
 // student object collection
 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")}
 };
 // Serialize the student collection object to get json characters
 string studentsJson = JsonMapper.ToJson (students);
 // response the string to the client
 context.Response.Write (studentsJson);
 context.Response.End ();
 }
 public bool IsReusable
 {
 get
 {
 return false;
 }
 }
 }
}
The results are as follows:

At this time, the date format is basically correct, as long as the date is instantiated directly in javascript,

var date = new Date ("01/31/2014 12:12:12");
alert (date.toLocaleString ());
The client code is as follows:

$ (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 ());
Method four:

This text was posted to the blog and some netizens put forward their valuable opinions. I did not consider the situation in MVC. In fact, MVC can also use handlers, so the difference is not great, but MVC has a special response for the server as JSON Action, the code is as follows:

using System;
using System.Web.Mvc;
namespace JSONDateMVC.Controllers
{
 public class HomeController: Controller
 {
 public JsonResult GetJson1 ()
 {
 // Serialize the current date and time object and allow client Get requests
 return Json (DateTime.Now, JsonRequestBehavior.AllowGet);
 }
 }
}
operation result:

Download a file with the content Application / json, the file name is GetJson1, and the content is "\ / Date (1391418272884) \ /"

From the above situation, it seems that serialization in MVC does not specifically deal with date formats. We can decompile to see the source code:

Json method called by Return:

protected internal JsonResult Json (object data, JsonRequestBehavior behavior)
{
 return this.Json (data, null, null, behavior);
}
this.Json method
protected internal virtual JsonResult Json (object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
 return new JsonResult {Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior};
}
Subclass of JsonResult class ActionResult class, ExecuteResult method:

From the above code, it is not difficult to see that Microsoft's JsonResult class still uses JavascriptSerializer, so the returned result is the same as when method 1 is not processed. To solve this problem we can derive a new class and override the ExecuteResult method Use Json.net to complete the serialization work. The code of the JsonResultPro.cs file is as follows:

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>
 /// date format
 /// </ 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)
 {
 // Convert System.DateTime date format to ISO 8601 date format
 // ISO 8601 (such as 2008-04-12T12: 53Z)
 IsoDateTimeConverter isoDateTimeConverter = new IsoDateTimeConverter ();
 // Set the date format
 isoDateTimeConverter.DateTimeFormat = DateTimeFormat;
 //Serialization
 String jsonResult = JsonConvert.SerializeObject (this.Data, isoDateTimeConverter);
 // corresponding result
 base2.Write (jsonResult);
 }
 }
 }
}
The code using the above JsonResultPro Action type is as follows:

 public JsonResultPro GetJson2 ()
 {
 // Serialize the current date and time object and allow the client Get request. Note that H is uppercase
 return new JsonResultPro (DateTime.Now, "yyyy-MM-dd HH: mm");
 }
operation result:

"2014-02-03 18:10"

In this way, you can set the date format exactly as you want, but you need to pay attention to the date format, such as the usual Format is different. For example, the H here indicates the time. There are several other questions to ask you:

1. There are many changes in the code obtained through Reflector decompilation. For example, the property will become the form of the get_Request () method. I don't know if there is a better way.

2. The resource file MvcResources.JsonRequest_GetNotAllowed is used in the decompiled code. How can it be used when rewriting?

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.