我将用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;
}
这个解决方案从回调方法中获取了我的对象,并使用日期格式库在页面上正确显示了日期。
我最终将“字符”添加到Panos的正则表达式中,以消除Microsoft序列化程序在将对象写入内联脚本时生成的字符:
所以,如果你的C#代码中有一个属性
protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}
在你的aspx中
<script type="text/javascript">
var myObject = '<%= JsonObject %>';
</script>
你会得到类似的东西
var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';
注意双引号。
为了将其转换为eval将正确反序列化的形式,我使用了:
myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
我使用原型,为了使用它,我添加了
String.prototype.evalJSONWithDates = function() {
var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
return jsonWithDates.evalJSON(true);
}
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))));
只是在这里添加另一种方法,WCF采用的“滴答方法”如果您不非常小心,如这里和其他地方所述,则很容易出现时区问题。所以我现在使用的是.NET和JavaScript都适当支持的ISO 8601格式,其中包括时区偏移。详情如下:
在WCF/.NET中:
其中CreationDate是System.DateTime;ToString(“o”)使用.NET的往返格式说明符,该说明符生成符合ISO 8601的日期字符串
new MyInfo {
CreationDate = r.CreationDate.ToString("o"),
};
在JavaScript中
在检索JSON之后,我使用接受ISO 8601日期字符串的Date构造函数将日期修正为JavaSriptDate对象。。。
$.getJSON(
"MyRestService.svc/myinfo",
function (data) {
$.each(data.myinfos, function (r) {
this.CreatedOn = new Date(this.CreationDate);
});
// Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
alert(data.myinfos[0].CreationDate.toLocaleString());
}
)
一旦有了JavaScript日期,就可以使用所有方便可靠的date方法,如toDateString、toLocaleString等。