Loading JSON Dates
JSON is a great format for serializing data, but unfortunately it does not support dates.
The Problem
If you serialize an object that contains date fields using JSON.stringify, the dates will be converted to strings. If you then parse the same object back using JSON.parse, they will remain strings.
Note how the "Date" column contains strings in the example below:
Id
Country
Sales
Expenses
Date
0
US
489.51
2,358.24
2017-02-08T12:47:06.405Z
1
Germany
7,803.20
2,513.54
2017-02-09T12:47:06.405Z
2
UK
9,996.58
2,616.71
2017-02-10T12:47:06.405Z
3
Japan
9,351.68
3,030.59
2017-02-10T12:47:06.405Z
4
Spain
349.51
7,358.24
/Date(1486561758556)/
Id
Country
Sales
Expenses
Date
0
The Solution
The solution for this problem is to use a 'reviver' function in the call to JSON.parse that will inspect the strings and convert those that look like dates into date objects.
Following is a grid showing the same data, this time parsed with a date reviver function:
Id
Country
Sales
Expenses
Date
0
US
489.51
2,358.24
2/8/2017
1
Germany
7,803.20
2,513.54
2/9/2017
2
UK
9,996.58
2,616.71
2/10/2017
3
Japan
9,351.68
3,030.59
2/10/2017
4
Spain
349.51
7,358.24
2/8/2017
Id
Country
Sales
Expenses
Date
0
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 | // This file locates: "Scripts/Lesson/C1Mvc/CVLoadingJsonDates.js". c1.documentReady(function () { // start with some data encoded as JSON // (as it would arrive from a server) var json = '[' + '{"id":0,"country":"US","sales":489.51,"expenses":2358.24,"date":"2017-02-08T12:47:06.405Z"},' + '{"id":1,"country":"Germany","sales":7803.20,"expenses":2513.54,"date":"2017-02-09T12:47:06.405Z"},' + '{"id":2,"country":"UK","sales":9996.58,"expenses":2616.71,"date":"2017-02-10T12:47:06.405Z"},' + '{"id":3,"country":"Japan","sales":9351.68,"expenses":3030.59,"date":"2017-02-10T12:47:06.405Z"},' + '{"id":4,"country":"Spain","sales":349.51,"expenses":7358.24,"date":"/Date(1486561758556)/"}' + ']' ; // decode the data // no special parsing for dates, the date field will contain strings var dataBad = JSON.parse(json); // show the bad data in a grid var theGridBad = wijmo.Control.getControl( '#theGridBad' ); theGridBad.itemsSource = dataBad; // decode the data // use with a Date reviver to restore date fields var dataGood = JSON.parse(json, function(key, value) { if ( typeof value === 'string' ) { // parse dates saved as JSON-strings var m = value.match(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/); if (m) { return new Date(Date.UTC(+m[1], +m[2] - 1, +m[3], +m[4], +m[5], +m[6])); } // parse dates saved as OData-style strings m = value.match(/^\/Date\((\d+)\)\/$/); if (m) { return new Date(parseInt(m[1])); } } return value; }); // show the good data in a grid var theGridGood = wijmo.Control.getControl( '#theGridGood' ); theGridGood.itemsSource = dataGood; }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System.Web.Mvc; namespace LearnMvcClient.Controllers { public partial class C1MvcController : Controller { // GET: CVLoadingJsonDates public ActionResult CVLoadingJsonDates() { return View(); } } } |
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 | < h1 > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Title) </ h1 > < p > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Text1) </ p > < h3 > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Title1) </ h3 > < p > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Text2) </ p > < p > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Text3) </ p > @Html .C1().FlexGrid().Id( "theGridBad" ) < h3 > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Title2) </ h3 > < p > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Text4) </ p > < p > @Html .Raw(Resources.C1Mvc.CVLoadingJsonDates_Text5) </ p > @Html .C1().FlexGrid().Id( "theGridGood" ) |