Convert JSON data to Moment

Former Member
Former Member
How can I convert a date value serialized in JSON to Moment?

E.g. a date is serialized as "Date":"\/Date(1488228437000+0100)\/" by a webservice I make my requests.

Thanks in advance!
  • The time looks to be "Unix Time". (The number of seconds since Jan 1,1970.) Not sure what the +0100 means

    This should do it:
    var now=new Time.Moment(unixTime);
    var today = Calendar.info(now, Time.FORMAT_MEDIUM);
  • Uhh.. That is not valid JSON. It looks like you may be receiving data that uses some system-specific extension. If you can, it would be good to fix the server side so that it provides JSON clean data (just the UTC timestamp should be sufficient). If you don't want to do that, then you need to extract the string, then you need to parse it.

    The code might look something like the following completely untested code...

    function onWebResponse(code, data) {

    if (code != 200) {
    return;
    }

    var date = data["Date"];

    // no real error checking

    // assumes '\/Date(...)\/'
    date = date.substring(7, date.length() - 3);

    var options = [
    "-",
    "Z",
    "+"
    ];

    var sign = 0;

    var pos;
    for (var i = 0; i < 3; ++i) {
    pos = date.find(options);
    if (pos != null) {
    sign = i - 1;
    break;
    }
    }

    // didn't find +, - or Z
    if (pos == null) {
    pos = date.length();
    }

    // exclude the milliseconds...
    var timestamp = date.substring(0, pos - 3).toNumber();

    if (sign != 0) {
    var offset = date.substring(pos + 1, date.length());

    // convert to a number in base 10
    offset = offset.toNumber();

    var hh = (offset / 100) * 3600;
    var mm = (offset % 100) * 60;

    // need to subtract the zone offset to get back to UTC time
    timestamp -= sign * (hh + mm);
    }

    // the value passed to the init method is a utc timestamp
    var moment = new Time.Moment(timestamp);

    // do something with moment...
    }
    [/code]
  • It does look like "1488228437000" is "Unix Time", but with mseconds.

    Right now, it's 1488234360, and the number has 3 extra trailing 0's
  • the number has 3 extra trailing 0's

    Not sure if you're replying to me... the code above uses pos - 3 to round down to the nearest second.

    Travis
  • Nope Travis, my earlier post about it being "Unix Time" :)
  • I've now had a chance to do some reading about the format used, and I've updated the code above.

    Travis
  • Former Member
    Former Member over 8 years ago
    "Uhh.. That is not valid JSON."

    It is serialized by .net's built in serializer in a REST API service built on WCF.
  • Former Member
    Former Member over 8 years ago
    Uhh.. That is not valid JSON. It looks like you may be receiving data that uses some system-specific extension. If you can, it would be good to fix the server side so that it provides JSON clean data (just the UTC timestamp should be sufficient). If you don't want to do that, then you need to extract the string, then you need to parse it.

    The code might look something like the following completely untested code...

    function onWebResponse(code, data) {

    if (code != 200) {
    return;
    }

    var date = data["Date"];

    // no real error checking

    // assumes '\/Date(...)\/'
    date = date.substring(7, date.length() - 3);

    var options = [
    "-",
    "Z",
    "+"
    ];

    var sign = 0;

    var pos;
    for (var i = 0; i < 3; ++i) {
    pos = date.find(options);
    if (pos != null) {
    sign = i - 1;
    break;
    }
    }

    // didn't find +, - or Z
    if (pos == null) {
    pos = date.length();
    }

    // exclude the milliseconds...
    var timestamp = date.substring(0, pos - 3).toNumber();

    if (sign != 0) {
    var offset = date.substring(pos + 1, date.length());

    // convert to a number in base 10
    offset = offset.toNumber();

    var hh = (offset / 100) * 3600;
    var mm = (offset % 100) * 60;

    timestamp += sign * (hh + mm);
    }

    // the value passed to the init method is a utc timestamp
    var moment = new Time.Moment(timestamp);

    // do something with moment...
    }
    [/code]

    Thanks, it works! :)

    I found 2 small bugs (mispellings) in it:
    date = date.substring(7, date.length() - 3); should be
    date = date.substring(6, date.length() - 3);

    and

    var mm = (offset % 100) * 60; should be
    var mm = (offset / 100) * 60;
  • I tested this code pretty thoroughly...

    date = date.substring(7, date.length() - 3); should be
    date = date.substring(6, date.length() - 3);


    I'm counting the bytes right now, and I see 7 characters in the string "\/Date(", which is exactly the string I want to skip. Maybe there is some confusion between what is documented to be returned ("\\/Date(...)\\/") and what is actually returned. When I read that string, I expect the first \ to be an escape for the second. Maybe once those are collapsed the result is an escape for the /?

    var mm = (offset % 100) * 60; should be
    var mm = (offset / 100) * 60;


    I'm pretty sure you want offset / 100 here. If you have the DST offset value +0130 (1 hour 30 minutes east of UTC), you want hh to be 1 and mm to be 30. 130 / 100 = 1, and 130 % 100 = 30, so those calculations are correct. You won't notice this in most cases because most time zones that people deal with are hours offset from UTC (mm would always be zero).

    Travis
  • If you have the moment in "now" and use this to break it down:

    var today = Calendar.info(now, Time.FORMAT_MEDIUM);

    It will already convert it to local time. It may be that you don't want to do anything with +/-/Z and the numbers following if that's there to adjust for the user's local time. Just something to watch for....