如何格式化 Microsoft JSON 日期?

我正在使用 jQuery 在Ajax 上进行首次尝试。我正在将数据存储到页面上,但是为 Date 数据类型返回的 JSON 数据遇到了一些麻烦。基本上,我得到的字符串看起来像这样:

/Date(1224043200000)/

从完全不熟悉 JSON 的人 - 如何将其格式化为短日期格式?是否应该在 jQuery 代码中的某个地方处理?我已经尝试使用$.datepicker.formatDate()尝试使用jQuery.UI.datepicker插件,但没有成功。

仅供参考:这是我结合以下答案使用的解决方案:

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;
}

该解决方案从回调方法中获取了我的对象,并使用日期格式库在页面上正确显示了日期。

答案

eval()是不必要的。这将正常工作:

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

substr()函数取出/Date(部分,而parseInt()函数获取整数,并在最后忽略)/ 。结果数字将传递到Date构造函数中。


我故意省略了基数( parseInt的第二个参数);见下面我的评论

另外,我完全同意Rory 的评论 :ISO-8601 日期优于此旧格式 - 因此,通常不应该将这种格式用于新开发。有关使用 ISO-8601 格式序列化日期的绝佳选择,请参见出色的Json.NET库。

对于 ISO-8601 格式的 JSON 日期,只需将字符串传递给Date构造函数即可:

var date = new Date(jsonDate); //no ugly parsing needed; full timezone support

您可以使用它从 JSON 获取日期:

var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));

然后,您可以使用JavaScript 日期格式脚本(最小化并压缩后为 1.2 KB)来根据需要显示它。

对于使用 Newtonsoft Json.NET 的用户 ,请阅读如何通过IE8,Firefox 3.5 和 Json.NET 中的 Native JSON 进行操作

同样,有关更改 Json.NET 编写的日期格式的文档也很有用: 使用 Json.NET 序列化日期

对于那些太懒惰的人,这里是快速的步骤。由于 JSON 具有松散的 DateTime 实现,因此您需要使用IsoDateTimeConverter() 。请注意,由于 Json.NET 4.5 的默认日期格式为 ISO,因此不需要以下代码。

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

JSON 将通过

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

最后,一些将 ISO 日期转换为 JavaScript 日期的 JavaScript:

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;
}

我这样用

$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);

原始示例:

/Date(1224043200000)/

当使用内置 JSON 序列化通过 WCF REST 发送日期时,不会反映 WCF 使用的格式。 (至少在. NET 3.5,SP1 上)

我发现这里的答案很有帮助,但是需要对正则表达式进行一些编辑,因为看起来时区 GMT 偏移量被附加到 WCF JSON 中返回的数字(自 1970 年以来)中。

在 WCF 服务中,我有:

[OperationContract]
[WebInvoke(
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.WrappedRequest
    )]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );

ApptVisitLinkInfo 的定义很简单:

public class ApptVisitLinkInfo {
    string Field1 { get; set; }
    DateTime Field2 { get; set; }
    ...
}

从服务中以 Json 形式返回 “Field2” 作为值时:

/Date(1224043200000-0600)/

请注意,时区偏移量是该值的一部分。

修改后的正则表达式:

/\/Date\((.*?)\)\//gi

有点急切,并且抓住了括号之间的所有内容,而不仅仅是第一个数字。产生的时间为 1970,加上时区偏移量都可以输入到 eval 中以获取日期对象。

用于替换的 JavaScript 代码如下:

replace(/\/Date\((.*?)\)\//gi, "new Date($1)");

不要重复自己 - 使用$.parseJSON()自动进行日期转换

帖子的答案提供了将日期手动转换为 JavaScript 日期的功能。我只扩展了 jQuery 的$.parseJSON()一点,因此它能够在您指示时自动解析日期。它处理 ASP.NET 格式的日期( /Date(12348721342)/ )以及 ISO 格式的日期( 2010-01-01T12.34.56.789Z ),这些日期由浏览器(和 json2.js 之类的库)中的本机 JSON 函数支持。

无论如何。如果您不想一遍又一遍地重复日期转换代码,建议您阅读此博客文章,并获取使您的生活更轻松的代码。

如果用 JavaScript 说

var thedate = new Date(1224043200000);
alert(thedate);

您会看到这是正确的日期,并且可以在任何框架的 JavaScript 代码中的任何地方使用该日期。

点击此处查看演示

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();

结果 -“10/15/2008”

更新

我们有一个内部 UI 库,必须同时应对 Microsoft 的 ASP.NET 内置 JSON 格式(如/Date(msecs)/最初在此处询问/Date(msecs)/以及大多数 JSON 的日期格式(包括 JSON.NET 的格式),如2014-06-22T00:00:00.0 。另外,我们需要应对oldIE 无法处理的任何其他问题(小数点后 3 位)

我们首先检测我们正在使用哪种日期,将其解析为普通的 JavaScript Date对象,然后将其格式化。

1)检测 Microsoft 日期格式

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

2)检测 ISO 日期格式

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)解析 MS 日期格式:

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

4)解析 ISO 日期格式。

我们至少有一种方法可以确保我们处理的是标准 ISO 日期或修改为始终具有 3 毫秒位置的 ISO 日期( 请参见上文 ),因此代码因环境而异。

4a)解析标准的 ISO 日期格式,以解决 oldIE 的问题:

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)使用固定的三毫秒小数位解析 ISO 格式 - 更加容易:

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

5)格式化:

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)绑在一起:

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

    return formatDate(d);
}

下面的旧答案对于将这种日期格式绑定到 jQuery 自己的 JSON 解析中很有用,这样您就可以获得 Date 对象而不是字符串,或者如果您仍然停留在 jQuery <1.5 以下。

旧答案

如果在 ASP.NET MVC 中使用 jQuery 1.4 的 Ajax 函数,则可以使用以下方法将所有 DateTime 属性转换为 Date 对象:

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

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

在 jQuery 1.5 中,可以通过使用 Ajax 调用中的 converters 选项避免全局重写parseJSON方法。

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

不幸的是,您必须切换到较旧的评估路线才能在全球范围内就地解析日期 - 否则,您需要在解析后根据具体情况对它们进行转换。

JSON 中没有内置的日期类型。这看起来像是某个时期的秒数 / 毫秒。如果您知道时代,则可以通过添加适当的时间来创建日期。

我还必须寻找解决此问题的方法,最终我遇到了 moment.js,这是一个不错的库,可以解析此日期格式以及更多其他内容。

var d = moment(yourdatestring)

它为我省去了一些麻烦,因此我想与您分享。 :)
您可以在这里找到有关它的更多信息: http : //momentjs.com/