36

Given the following JSON Date representation:

"\/Date(1221644506800-0700)\/"

How do you deserialize this into it's JavaScript Date-type form?

I've tried using MS AJAX JavaScrioptSerializer as shown below:

Sys.Serialization.JavaScriptSerializer.deserialize("\/Date(1221644506800-0700)\/")

However, all I get back is the literal string date.

Muntasir
  • 798
  • 1
  • 14
  • 24
Brian Chavez
  • 8,048
  • 5
  • 54
  • 47
  • Are you using jQuery maybe? Check my blog post to auto convert dates so you don't have to do it manually. http://erraticdev.blogspot.com/2010/12/converting-dates-in-json-strings-using.html – Robert Koritnik Dec 27 '10 at 15:51
  • See my comments below. Your blog's code fails on dates before the epoch. – Josh Pearce Nov 28 '11 at 18:16

7 Answers7

30

Provided you know the string is definitely a date I prefer to do this :

 new Date(parseInt(value.replace("/Date(", "").replace(")/",""), 10))
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
18

Bertrand LeRoy, who worked on ASP.NET Atlas/AJAX, described the design of the JavaScriptSerializer DateTime output and revealed the origin of the mysterious leading and trailing forward slashes. He made this recommendation:

run a simple search for "\/Date((\d+))\/" and replace with "new Date($1)" before the eval (but after validation)

I implemented that as:

var serializedDateTime = "\/Date(1271389496563)\/";
document.writeln("Serialized: " + serializedDateTime + "<br />");

var toDateRe = new RegExp("^/Date\\((\\d+)\\)/$");
function toDate(s) {
    if (!s) {
        return null;
    }
    var constructor = s.replace(toDateRe, "new Date($1)");
    if (constructor == s) {
        throw 'Invalid serialized DateTime value: "' + s + '"';
    }
    return eval(constructor);
}

document.writeln("Deserialized: " + toDate(serializedDateTime) + "<br />");

This is very close to the many of the other answers:

  • Use an anchored RegEx as Sjoerd Visscher did -- don't forget the ^ and $.
  • Avoid string.replace, and the 'g' or 'i' options on your RegEx. "/Date(1271389496563)//Date(1271389496563)/" shouldn't work at all.
ESV
  • 7,620
  • 4
  • 39
  • 29
  • 1
    A very good answer.... shame i found it at the bottom of the list for the question. – GordonBy Apr 29 '10 at 11:37
  • 6
    That regex won't work for dates before the epoch, which have a negative value. You need something like this: `/\/Date\((-?\d+)(?:-\d+)?\)\//i` – Josh Pearce Nov 28 '11 at 16:18
11

A JSON value is a string, number, object, array, true, false or null. So this is just a string. There is no official way to represent dates in JSON. This syntax is from the asp.net ajax implementation. Others use the ISO 8601 format.

You can parse it like this:

var s = "\/Date(1221644506800-0700)\/";
var m = s.match(/^\/Date\((\d+)([-+]\d\d)(\d\d)\)\/$/);
var date = null;
if (m)
  date = new Date(1*m[1] + 3600000*m[2] + 60000*m[3]);
Sjoerd Visscher
  • 11,840
  • 2
  • 47
  • 59
  • My toJson method was spitting out serialized dates as "\/Date(1251795070160)\/", which your code doesn't parse. I'll work out why later, just posting here for others – CVertex Sep 01 '09 at 12:21
  • +1 for making it clear what a JSON value can be and that dates are not one of them, but a custom format. – René Sep 29 '11 at 14:20
  • That regex won't work for dates before the epoch, which have a negative value. You need this: `/\/Date\((-?\d+)(?:-\d+)?\)\//i` – Josh Pearce Nov 28 '11 at 16:17
  • @Sjoerd: Do you have to add the timezone or subtract it to convert it to UTC? I am confused because if I see a time as `1/1/2000 0:0:0 +0500` (i think) I have to subtract 5 hours to get UTC time. – Salman A May 16 '12 at 16:42
  • You could fallback to parseInt if no timezone is specified `if (date == null) date = new Date(parseInt(s.substring(6, s.length - 2), 10));` – Gideon Mulder Jun 22 '17 at 08:18
6

The regular expression used in the ASP.net AJAX deserialize method looks for a string that looks like "/Date(1234)/" (The string itself actually needs to contain the quotes and slashes). To get such a string, you will need to escape the quote and back slash characters, so the javascript code to create the string looks like "\"\/Date(1234)\/\"".

This will work.

Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800)\\/\"")

It's kind of weird, but I found I had to serialize a date, then serialize the string returned from that, then deserialize on the client side once.

Something like this.

Script.Serialization.JavaScriptSerializer jss = new Script.Serialization.JavaScriptSerializer();
string script = string.Format("alert(Sys.Serialization.JavaScriptSerializer.deserialize({0}));", jss.Serialize(jss.Serialize(DateTime.Now)));
Page.ClientScript.RegisterStartupScript(this.GetType(), "ClientScript", script, true);
Kyle Jones
  • 536
  • 3
  • 5
  • The problem with this method is that it doesn't look at the timezone: Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800+0200)\\/\"") Will results the same as: Sys.Serialization.JavaScriptSerializer.deserialize("\"\\/Date(1221644506800+0300)\\/\"") – Gideon Mulder Jun 22 '17 at 08:10
3

For those who don't want to use Microsoft Ajax, simply add a prototype function to the string class.

E.g.

    String.prototype.dateFromJSON = function () {
    return eval(this.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
};

Don't want to use eval? Try something simple like

var date = new Date(parseInt(jsonDate.substr(6)));

As a side note, I used to think Microsoft was misleading by using this format. However, the JSON specification is not very clear when it comes to defining a way to describe dates in JSON.

Alex Nolasco
  • 18,750
  • 9
  • 86
  • 81
  • 2
    That regex won't work for dates before the epoch, which have a negative value. You need this: `/\/Date\((-?\d+)(?:-\d+)?\)\//i` – Josh Pearce Nov 28 '11 at 16:28
2

Actually, momentjs supports this kind of format, you might do something like:

    var momentValue = moment(value);

    momentValue.toDate();

This returns the value in a javascript date format

tavo
  • 41
  • 2
1

The big number is the standard JS time

new Date(1221644506800)

Wed Sep 17 2008 19:41:46 GMT+1000 (EST)

Daniel
  • 4,847
  • 1
  • 23
  • 19