题 如何格式化Microsoft JSON日期?


我正在接受我的第一次破解 阿贾克斯 用jQuery。我将数据放到我的页面上,但是我在为Date数据类型返回的JSON数据方面遇到了一些麻烦。基本上,我得到的字符串看起来像这样:

/Date(1224043200000)/

从全新的人到JSON - 如何将其格式化为短日期格式?这应该在jQuery代码中的某个地方处理吗?我试过了 jQuery.UI.datepicker 插件使用 $.datepicker.formatDate() 没有任何成功。

仅供参考:这是我提出的解决方案,结合了以下答案:

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

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


1793


起源


这可能很有趣: hanselman.com/blog/... - citronas
/Date(...)/格式特定于Microsoft的内置JSON日期格式 - 它不是任何标准的一部分,而来自Javascript的JSON有一个标准:ISO格式Javascript指定: stackoverflow.com/a/15952652/176877  因此,此问题特定于Microsoft的JSON日期格式。我修改了标题以澄清这一点。 - Chris Moschini
你在开玩笑!微软已经在JSON上盖章了!并在日期!!他们什么时候学习! - Nick.McDermaid
在.NET端使用Newtonsoft JSON并在JS端有很好的类型值,只需使用: github.com/RickStrahl/json.date-extensions - baHI


答案:


Eval不是必需的。这样可以正常工作:

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

substr函数取出“/ Date(”部分,并且parseInt函数获取整数并忽略最后的“)/”。生成的数字将传递到Date构造函数中。

编辑:我故意遗漏了基数(第二个参数为parseInt);看到 我的评论如下。另外,我完全同意 罗里的评论:ISO-8601日期比旧格式更受欢迎 - 因此这种格式通常不应用于新开发。看到优秀 Json.NET 库是一个很好的选择,使用ISO-8601格式序列化日期。

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

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

1566



@Broam:如果MS改变格式,两种方法(替换功能和这个答案)都必须改变。 - Roy Tinker
@LeeWhitney:是的,但它会忽略后缀(这是一个时区偏移)。 parseInt函数从传递给它的字符串的前面抓取数字,直到它遇到非数字字符或字符串的结尾,此时它停止并返回数字结果。 - Roy Tinker
你能用radix var date = new Date(parseInt(jsonDate.substr(6),10))来更新它吗? - James Kyburz
@JamesKyburz:每个规则都有例外,我认为这是一个例外情况。来自.NET的JSON日期编号 决不 有一个领先的“0”,所以我们可以安全地省略基数。 - Roy Tinker
值得注意的是,这种日期格式非常糟糕,一般的举措是用JSON中的ISO-8601格式化日期。看到 hanselman.com/blog/... - Rory


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

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

然后你可以使用 JavaScript日期格式 脚本(缩小和压缩时为1.2 KB)以根据需要显示它。


115



该行没有任何问题,序列是\ //。第一个斜杠被转义,所以它不像评论那样算。这是你的编辑欺骗你,线路将正常工作。 - andreialecu
@rball,胡说八道: jsonDate = new Date(+jsonDate.replace(/\/Date\((\d+)\)\//, '$1')); - eyelidlessness
pst是正确的,没有'eval'可以通过各种方式实现。 Crockford说“eval Is Evil”因为它的可读性较低而且安全性较低,而且他可能进一步暗示它效率更低,更危险,因为它击中了javascript编译器。 - Mark Rogers
@Edy: new Function 几乎和。一样糟糕 eval: dev.opera.com/articles/view/efficient-javascript/... - Marcel Korpel
@Edy:这是另一种形式的评价,就像'邪恶'一样。解析字符串(参见下面的答案) - Roy Tinker


对于那些使用Newtonsoft的人 Json.NET,阅读如何通过 IE8中的原生JSON,Firefox 3.5加上Json.NET

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

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

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

JSON将通过as

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

最后,一些JavaScript将ISO日期转换为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);

84



JavaScript Date构造函数可以为您解析字符串: new Date("2009-04-12T20:44:55") - David Hogue
警告 - Date()构造函数格式和解析在ECMAScript 6之前是非标准的。例如,IE 9将构造函数的日期视为本地时间,即使它在IS0-8601中,其他地方也暗示为UCT。如果您支持旧浏览器,请不要依赖日期构造函数。 codeofmatt.com/2013/06/07/... - DanO
发送非UTC日期迟早会让您遇到麻烦。 - tymtam


原来的例子:

/Date(1224043200000)/  

不反映WCF使用内置JSON序列化通过WCF REST发送日期时使用的格式。 (至少在.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; }
    ...
}

当“Field2”作为Json从服务返回时,值为:

/Date(1224043200000-0600)/

注意作为值的一部分包含的时区偏移量。

修改后的正则表达式:

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

它稍微有点急切,抓住了parens之间的一切,而不仅仅是第一个数字。产生的时间是1970年的时间,加上时区偏移量都可以输入到eval中以获得日期对象。

替换的JavaScript结果是:

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

57



这是错误的,新的日期(1224043200000-0600)将只从日期减去600,在这种情况下600毫秒,而不是6小时。 - ariel
@ariel:看看吧 Javascript日期从毫秒 和时区 - Bergi
我认为只有在.NET中的DateTime对象上有时区(这是默认行为)时才会包含时区偏移量。如果您的日期是UTC,请使用DateTime.SpecifyKind(date,DateTimeKind.UTC),并在序列化时获得正确的UTC值,没有偏移量,然后您可以根据需要将其转换回用户的时区。如果是在当地时间,请使用.ToUniversalTime(),它将转换为UTC,并且已经为您指定了“Kind”。 - jvenema
在javascript -0100中将是一个二进制字符串,所以要小心! - verbedr
一旦你有从WCF转换为JS的日期,那么反向怎么样。你必须将日期作为整数(使用date.getTime())来传递给同一个WCF吗? - NitinSingh


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

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

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


53





如果你用JavaScript说,

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

您将看到它是正确的日期,并且您可以在任何框架的JavaScript代码中的任何位置使用它。


50



这也是我想到的,除非它最终成为:var thedate = / Date(1224043200000)/;至少对于我来说... - rball
日期()和日期(1224043200000)在Chrome和Firefox中都提供相同的结果。不确定这是否适用于旧浏览器,但这个答案现在在浏览器中不起作用。 - James
@James,是的,它提供浏览器当前日期。 :( - vissu
您需要将其写为“新日期(1224043200000)”。 - BrainSlugs83


点击这里查看演示

的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”


47



只是对上述方法的改进。 function formatearFecha(fec){var value = new Date(parseInt(fec.replace(/(^。*()|([+ - ]。* $)/ g,''))); var mes = value.getMonth (); var dia = value.getDate(); var date = dia +“/”+ mes +“/”+ value.getFullYear(); if(dia <10)date = date.substr(0,0)+ '0'+ dia + date.substr(1); if(mes <10)date = date.substr(0,3)+'0'+ mes + date.substr(4); return date;}日期格式化为ddMMyyyy。干杯! - Matias
喔!非常感谢!!!它真的让我的月份。 - Raihan Ridoy