How do I format a Microsoft JSON date?

2018-12-31 00:17发布

I'm taking my first crack at Ajax with jQuery. I'm getting my data onto my page, but I'm having some trouble with the JSON data that is returned for Date data types. Basically, I'm getting a string back that looks like this:

/Date(1224043200000)/

From someone totally new to JSON - How do I format this to a short date format? Should this be handled somewhere in the jQuery code? I've tried the jQuery.UI.datepicker plugin using $.datepicker.formatDate() without any success.

FYI: Here's the solution I came up with using a combination of the answers here:

function getMismatch(id) {
  $.getJSON("Main.aspx?Callback=GetMismatch",
    { MismatchId: id },

    function (result) {
      $("#AuthMerchId").text(result.AuthorizationMerchantId);
      $("#SttlMerchId").text(result.SettlementMerchantId);
      $("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
      $("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
      $("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
      $("#LastUpdatedBy").text(result.LastUpdateNt);
      $("#ProcessIn").text(result.ProcessIn);
    }
  );

  return false;
}

function formatJSONDate(jsonDate) {
  var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
  return newDate;
}

This solution got my object from the callback method and displayed the dates on the page properly using the date format library.

30条回答
明月照影归
2楼-- · 2018-12-31 00:23

Updated

We have an internal UI library that has to cope with both Microsoft's ASP.NET built-in JSON format, like /Date(msecs)/, asked about here originally, and most JSON's date format including JSON.NET's, like 2014-06-22T00:00:00.0. In addition we need to cope with oldIE's inability to cope with anything but 3 decimal places.

We first detect what kind of date we're consuming, parse it into a normal JavaScript Date object, then format that out.

1) Detect Microsoft Date format

// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
    return /^\/Date\(/.test(s);
}

2) Detect ISO date format

var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;

function looksLikeIsoDate(s) {
    return isoDateRegex.test(s);
}

3) Parse MS date format:

function parseMSDate(s) {
    // Jump forward past the /Date(, parseInt handles the rest
    return new Date(parseInt(s.substr(6)));
}

4) Parse ISO date format.

We do at least have a way to be sure that we're dealing with standard ISO dates or ISO dates modified to always have three millisecond places (see above), so the code is different depending on the environment.

4a) Parse standard ISO Date format, cope with oldIE's issues:

function parseIsoDate(s) {
    var m = isoDateRegex.exec(s);

    // Is this UTC, offset, or undefined? Treat undefined as UTC.
    if (m.length == 7 ||                // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
        (m.length > 7 && (
            !m[7] ||                    // Array came back length 9 with undefined for 7 and 8
            m[7].charAt(0) != '.' ||    // ms portion, no tz offset, or no ms portion, Z
            !m[8] ||                    // ms portion, no tz offset
            m[8] == 'Z'))) {            // ms portion and Z
        // JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
        var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
    } else {
        // local
        var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
    }

    return d;
}

4b) Parse ISO format with a fixed three millisecond decimal places - much easier:

function parseIsoDate(s) {
    return new Date(s);
}

5) Format it:

function hasTime(d) {
    return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}

function zeroFill(n) {
    if ((n + '').length == 1)
        return '0' + n;

    return n;
}

function formatDate(d) {
    if (hasTime(d)) {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
        s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
    } else {
        var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
    }

    return s;
}

6) Tie it all together:

function parseDate(s) {
    var d;
    if (looksLikeMSDate(s))
        d = parseMSDate(s);
    else if (looksLikeIsoDate(s))
        d = parseIsoDate(s);
    else
        return null;

    return formatDate(d);
}

The below old answer is useful for tying this date formatting into jQuery's own JSON parsing so you get Date objects instead of strings, or if you're still stuck in jQuery <1.5 somehow.

Old Answer

If you're using jQuery 1.4's Ajax function with ASP.NET MVC, you can turn all DateTime properties into Date objects with:

// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};

$.ajax({
    ...
    dataFilter: function(d) {
        return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
    },
    ...
});

In jQuery 1.5 you can avoid overriding the parseJSON method globally by using the converters option in the Ajax call.

http://api.jquery.com/jQuery.ajax/

Unfortunately you have to switch to the older eval route in order to get Dates to parse globally in-place - otherwise you need to convert them on a more case-by-case basis post-parse.

查看更多
谁念西风独自凉
3楼-- · 2018-12-31 00:23

Using the jQuery UI datepicker - really only makes sense if you're already including jQuery UI:

$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6)))); 

output:

October 15, 2008

查看更多
大哥的爱人
4楼-- · 2018-12-31 00:24

Click here to check the Demo

JavaScript/jQuery

var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
            (
                 parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
            );
var dat = value.getMonth() +
                         1 +
                       "/" +
           value.getDate() +
                       "/" +
       value.getFullYear();

Result - "10/15/2008"

查看更多
像晚风撩人
5楼-- · 2018-12-31 00:24

There is no built in date type in JSON. This looks like the number of seconds / milliseconds from some epoch. If you know the epoch you can create the date by adding on the right amount of time.

查看更多
余欢
6楼-- · 2018-12-31 00:24

This may can also help you.

 function ToJavaScriptDate(value) { //To Parse Date from the Returned Parsed Date
        var pattern = /Date\(([^)]+)\)/;
        var results = pattern.exec(value);
        var dt = new Date(parseFloat(results[1]));
        return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
    }
查看更多
荒废的爱情
7楼-- · 2018-12-31 00:25

For those using Newtonsoft Json.NET, read up on how to do it via Native JSON in IE8, Firefox 3.5 plus Json.NET.

Also the documentation on changing the format of dates written by Json.NET is useful: Serializing Dates with Json.NET

For those that are too lazy, here are the quick steps. As JSON has a loose DateTime implementation, you need to use the IsoDateTimeConverter(). Note that since Json.NET 4.5 the default date format is ISO so the code below isn't needed.

string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());

The JSON will come through as

"fieldName": "2009-04-12T20:44:55"

Finally, some JavaScript to convert the ISO date to a JavaScript date:

function isoDateReviver(value) {
  if (typeof value === 'string') {
    var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
      if (a) {
        var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
        return new Date(utcMilliseconds);
      }
  }
  return value;
}

I used it like this

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
查看更多
登录 后发表回答