Javascript Dates are Weird

Dates in javascript are weird. There, I said it.

This last week I got stung a few times working with dates that were being sent back from an MVC controller action in JSON format.

I'm throwing together this quick little page to help me remember in the future what I figured out today.

First, javascript dates follow the ISO 8601 standard. That's the one with the "T" in the middle of the long date/time string. This is an example of one

2014-09-26T08:15:47.1300000-05:00

If you take that string and pass it as an argument to a javascript Date constructor, you'll get a live Date object.

Now, the problem I ran into was that sometimes I was getting Date results in JSON strings that looked like this, rather than an ISO string:

"/Date(1411707600000)/"

This is how Microsoft will encode dates in an HTTP response. It's an integer value representing the number of ticks since the epoch.

After a little bit of looking, I found the reason for the encoding differences. It all has to do with whether or not you're returning a raw C# DateTime object, or a string. Here's an example action method which takes the current date and then encodes it three different ways:

        [HttpGet]
        public ActionResult DateFormatting()
        {
            var thedate = DateTime.Today;
            return new JsonResult
            {
                Data = new
                {
                    RawDate = thedate,
                    JsonSerialized = JsonConvert.SerializeObject(thedate),   
                    DateTimeToString = thedate.ToString("o")
                },
                JsonRequestBehavior = JsonRequestBehavior.AllowGet
            };
        }

Here are the results in JSON format. Note that when we just return a raw DateTime object from MVC it gets Microsoft encoded. If we use the Newtonsoft JsonConvert method then we get a nicely formatted ISO string. Finally, if we use the built in ToString method on DateTime and specify 'o' for iso, then we get a similarly formatted ISO string.

 {
    "RawDate": "/Date(1411707600000)/",
    "JsonSerialized": "\"2014-09-26T00:00:00-05:00\"",
    "DateTimeToString": "2014-09-26T00:00:00.0000000-05:00"
}

Going forward I'm going to make sure that I just run everything through JsonConvert before passing it back to the client. I've found that it's much easier to work with the native ISO strings in javascript, especially when you start having to deal with timezone differences.

Hope this helps.