我将用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;
}

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


当前回答

所有这些答案都有一个共同点:它们都将日期存储为单个值(通常是字符串)。

另一种选择是利用JSON的固有结构,将日期表示为数字列表:

{ "name":"Nick",
  "birthdate":[1968,6,9] }

当然,你必须确保对话的两端都同意格式(年、月、日),以及哪些字段是日期,。。。但是它具有完全避免日期到字符串转换问题的优点。都是数字,根本没有字符串。此外,使用顺序:年、月、日也允许按日期进行正确排序。

只需跳出框来思考——JSON日期不必存储为字符串。

这样做的另一个好处是,通过利用CouchDB处理数组值查询的方式,您可以轻松(高效)选择给定年份或月份的所有记录。

其他回答

单击此处查看演示

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

结果-“2008年10月15日”

对于使用Newtonsoft Json.NET的用户,请阅读如何在IE8、Firefox 3.5和Json.NET中通过原生Json实现。

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

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

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

JSON将作为

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

eval()不是必需的。这将很好:

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

substr()函数取出/Date(部分),parseInt()函数获取整数并忽略结尾处的)/。生成的数字被传递到Date构造函数中。


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

此外,我完全同意Rory的评论:ISO-8601日期比这种旧格式更可取,因此这种格式通常不应用于新的开发。

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

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

TLDR:无法可靠地转换仅日期值,请发送字符串。。。

……或者至少这是所有这些答案的开始。

这里出现了许多转换问题。

这是一个没有时间的日期

每个人似乎都缺少的一点是,问题中有多少个尾随的零-它几乎可以肯定是从一个没有时间的日期开始的:

/Date(1224043200000)/

当从javascript控制台将其作为新日期执行时(许多答案的基础)

new Date(1224043200000)

你得到:

最初的询问者可能在EST中,并且有一个带有午夜的纯日期(sql)或DateTime(而不是DateTimeOffset)。

换句话说,这里的意图是时间部分没有意义。但是,如果浏览器在与生成的服务器相同的时区执行此操作,则无所谓,大多数答案都有效。

按时区排序

但是,如果您在不同时区(例如PST)的计算机上执行上述代码:

你会注意到,我们现在在另一个时区落后了一天。这不会通过更改序列化程序来解决(它仍将以iso格式包含时区)

问题

Date(sql)和DateTime(.net)上没有时区,但一旦将它们转换为可以执行的操作(在本例中是通过json推断的javascript),.net中的默认操作就是假定当前时区。

序列化正在创建的数字是自Unix纪元以来的毫秒数,或者:

(DateTimeOffset.Parse("10/15/2008 00:00:00Z") - DateTimeOffset.Parse("1/1/1970 00:00:00Z")).TotalMilliseconds;

javascript中的新Date()将其作为参数。Epoch来自UTC,所以无论您是否想要,现在您都可以在其中获得时区信息。

可能的解决方案:

在序列化对象上创建一个仅表示日期的字符串属性可能会更安全——带有“10/15/2008”的字符串不太可能将其他人与此混淆。尽管即使在那里,您也必须在解析方面小心:https://stackoverflow.com/a/31732581

然而,本着对所提问题提供答案的精神,如下:

function adjustToLocalMidnight(serverMidnight){ 
  var serverOffset=-240; //injected from model? <-- DateTimeOffset.Now.Offset.TotalMinutes
  var localOffset=-(new Date()).getTimezoneOffset(); 
  return new Date(date.getTime() + (serverOffset-localOffset) * 60 * 1000)
}

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

另外,KendoUI支持转换Microsoft JSON日期。因此,如果您的项目引用了“KendoUI”,您可以简单地使用

var newDate = kendo.parseDate(jsonDate);