ASP.NET MVC JsonResult Date Format

Viewed 198126

I have a controller action that effectively simply returns a JsonResult of my model. So, in my method I have something like the following:

return new JsonResult(myModel);

This works well, except for one problem. There is a date property in the model and this appears to be returned in the Json result like so:

"\/Date(1239018869048)\/"

How should I be dealing with dates so they are returned in the format I require? Or how do I handle this format above in script?

25 Answers

Just to expand on casperOne's answer.

The JSON spec does not account for Date values. MS had to make a call, and the path they chose was to exploit a little trick in the javascript representation of strings: the string literal "/" is the same as "\/", and a string literal will never get serialized to "\/" (even "\/" must be mapped to "\\/").

See http://msdn.microsoft.com/en-us/library/bb299886.aspx#intro_to_json_topic2 for a better explanation (scroll down to "From JavaScript Literals to JSON")

One of the sore points of JSON is the lack of a date/time literal. Many people are surprised and disappointed to learn this when they first encounter JSON. The simple explanation (consoling or not) for the absence of a date/time literal is that JavaScript never had one either: The support for date and time values in JavaScript is entirely provided through the Date object. Most applications using JSON as a data format, therefore, generally tend to use either a string or a number to express date and time values. If a string is used, you can generally expect it to be in the ISO 8601 format. If a number is used, instead, then the value is usually taken to mean the number of milliseconds in Universal Coordinated Time (UTC) since epoch, where epoch is defined as midnight January 1, 1970 (UTC). Again, this is a mere convention and not part of the JSON standard. If you are exchanging data with another application, you will need to check its documentation to see how it encodes date and time values within a JSON literal. For example, Microsoft's ASP.NET AJAX uses neither of the described conventions. Rather, it encodes .NET DateTime values as a JSON string, where the content of the string is /Date(ticks)/ and where ticks represents milliseconds since epoch (UTC). So November 29, 1989, 4:55:30 AM, in UTC is encoded as "\/Date(628318530718)\/".

A solution would be to just parse it out:

value = new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10));

However I've heard that there is a setting somewhere to get the serializer to output DateTime objects with the new Date(xxx) syntax. I'll try to dig that out.


The second parameter of JSON.parse() accepts a reviver function where prescribes how the value originally produced by, before being returned.

Here is an example for date:

var parsed = JSON.parse(data, function(key, value) {
  if (typeof value === 'string') {
    var d = /\/Date\((\d*)\)\//.exec(value);
    return (d) ? new Date(+d[1]) : value;
  }
  return value;
});

See the docs of JSON.parse()

Using jQuery to auto-convert dates with $.parseJSON

Note: this answer provides a jQuery extension that adds automatic ISO and .net date format support.

Since you're using Asp.net MVC I suspect you're using jQuery on the client side. I suggest you read this blog post that has code how to use $.parseJSON to automatically convert dates for you.

Code supports Asp.net formatted dates like the ones you mentioned as well as ISO formatted dates. All dates will be automatically formatted for you by using $.parseJSON().

I had the same problem and instead of returning the actual date value I just used ToString("dd MMM yyyy") on it. Then in my javascript I used new Date(datevalue), where datevalue may be "01 Jan 2009".

See this thread:

http://forums.asp.net/p/1038457/1441866.aspx#1441866

Basically, while the Date() format is valid javascript, it is NOT valid JSON (there is a difference). If you want the old format, you will probably have to create a facade and transform the value yourself, or find a way to get at the serializer for your type in the JsonResult and have it use a custom format for dates.

Not the most elegant way but this worked for me:

var ms = date.substring(6, date.length - 2);
var newDate = formatDate(ms);


function formatDate(ms) {

    var date = new Date(parseInt(ms));
    var hour = date.getHours();
    var mins = date.getMinutes() + '';
    var time = "AM";

    // find time 
    if (hour >= 12) {
        time = "PM";
    }
    // fix hours format
    if (hour > 12) {
        hour -= 12;
    }
    else if (hour == 0) {
        hour = 12;
    }
    // fix minutes format
    if (mins.length == 1) {
        mins = "0" + mins;
    }
    // return formatted date time string
    return date.getMonth() + 1 + "/" + date.getDate() + "/" + date.getFullYear() + " " + hour + ":" + mins + " " + time;
}

I found this to be the easiest way to change it server side.

using System.Collections.Generic;
using System.Web.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace Website
{
    /// <summary>
    /// This is like MVC5's JsonResult but it uses CamelCase and date formatting.
    /// </summary>
    public class MyJsonResult : ContentResult
    {
        private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver(),
            Converters = new List<JsonConverter> { new StringEnumConverter() }
        };

        public FindersJsonResult(object obj)
        {
            this.Content = JsonConvert.SerializeObject(obj, Settings);
            this.ContentType = "application/json";
        }
    }
}

I had a number of issues come up with JSON dates and decided to just get rid of the problem by addressing the date issue in the SQL. Change the date format to a string format

select flddate from tblName

select flddate, convert(varchar(12), flddate, 113) as fldDateStr from tblName

By using the fldDateStr the problem dissappeared and I could still use the date field for sorting or other purposes.

0

In your cshtml,

<tr ng-repeat="value in Results">                
 <td>{{value.FileReceivedOn | mydate | date : 'dd-MM-yyyy'}} </td>
</tr>

In Your JS File, maybe app.js,

Outside of app.controller, add the below filter.

Here the "mydate" is the function which you are calling for parsing the date. Here the "app" is the variable which contains the angular.module

app.filter("mydate", function () {
    var re = /\/Date\(([0-9]*)\)\//;
    return function (x) {
        var m = x.match(re);
        if (m) return new Date(parseInt(m[1]));
        else return null;
    };
});
Related