如何格式化Microsoft JSONdate?
我正在使用jQuery在Ajax上进行第一次破解。 我正在将我的数据放到我的页面上,但是对于Date数据types返回的JSON数据,我遇到了一些麻烦。 基本上,我得到一个string,看起来像这样:
/Date(1224043200000)/
从全新到JSON – 如何将其格式化为短date格式? 这应该在jQuery代码中的某处处理? 我已经尝试使用$.datepicker.formatDate()
没有任何成功的jQuery.UI.datepicker
插件。
仅供参考:下面是我在这里结合使用这些答案的解决scheme:
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; }
该解决scheme从callback方法中得到了我的对象,并使用date格式库正确显示了页面上的date。
评估是没有必要的。 这将工作正常:
var date = new Date(parseInt(jsonDate.substr(6)));
substr函数取出“/ Date(”部分,parseInt函数获取整数,最后忽略“)/”。 生成的数字被传递给Date构造函数。
编辑:我有意遗漏了基数(第二个参数parseInt); 看到我下面的评论 。 另外,我完全同意Rory的评论 :ISO-8601date比这个旧格式更受欢迎 – 所以这种格式通常不应该用于新的开发。 查看优秀的Json.NET库,以便使用ISO-8601格式序列化date。
对于ISO-8601格式化的JSONdate,只需将该string传递给Date构造函数:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
你可以用这个从JSON获取date:
var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
然后,您可以使用JavaScriptdate格式脚本(缩小和压缩后为1.2 KB)来按需要显示它。
对于那些使用Newtonsoft Json.NET的人 ,请阅读如何通过IE8中的Native JSON,Firefox 3.5和Json.NET来实现 。
此外,有关更改Json.NET写入date格式的文档很有用: 使用Json.NET序列化date
对于那些懒惰的人来说,这里是快速的步骤。 由于JSON有一个松散的DateTime实现,所以你需要使用IsoDateTimeConverter()
。 请注意,由于Json.NET 4.5的默认date格式是ISO,所以下面的代码是不需要的。
string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());
JSON将通过
"fieldName": "2009-04-12T20:44:55"
最后,一些将ISOdate转换为JavaScriptdate的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)/
并不反映WCF在使用内置的JSON序列化通过WCF REST发送date时使用的格式。 (至less在.NET 3.5,SP1)
我发现这里的答案很有帮助,但是需要对正则expression式进行轻微的修改,因为在WCF JSON中,时区GMT偏移量被附加到返回的数字(自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)/
注意包含的时区偏移作为值的一部分。
修改后的正则expression式:
/\/Date\((.*?)\)\//gi
它稍微更加热切,并且抓住了所有人之间的一切,而不仅仅是第一个数字。 结果1970年的时间,加上时区偏移量都可以input到eval中以获取date对象。
由此产生的JavaScript代替行是:
replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
不要重复自己 – 使用$.parseJSON()
自动化date转换
您的post的答案提供手动date转换为JavaScriptdate。 我已经扩展了jQuery的$.parseJSON()
,所以它可以自动parsingdate,当你指示它。 它处理浏览器中的本地JSON函数(以及像json2.js这样的库)所支持的ASP.NET格式的date( /Date(12348721342)/
)以及ISO格式的date( 2010-01-01T12.34.56.789Z
)。
无论如何。 如果你不想一遍又一遍地重复你的date转换代码,我build议你阅读这个博客文章,并获得将使你的生活更容易一些的代码。
点击这里查看演示
的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日”
如果你用JavaScript说,
var thedate = new Date(1224043200000); alert(thedate);
你会看到这是正确的date,你可以在任何地方使用任何框架的JavaScript代码。
更新
我们有一个内部的用户界面库,它必须同时处理微软的ASP.NET内置的JSON格式,如/Date(msecs)/
,最初在这里被问到,以及大多数JSON的date格式,包括JSON.NET,比如2014-06-22T00:00:00.0
。 此外,我们需要应付oldIE无力应付任何事情,但小数点后三位 。
我们首先检测我们正在使用的datetypes,将其parsing为正常的JavaScript Date
对象,然后将其格式化。
1)检测Microsoftdate格式
// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/' function looksLikeMSDate(s) { return /^\/Date\(/.test(s); }
2)检测ISOdate格式
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)parsingMSdate格式:
function parseMSDate(s) { // Jump forward past the /Date(, parseInt handles the rest return new Date(parseInt(s.substr(6))); }
4)parsingISOdate格式。
我们至less有办法确定我们正在处理标准的ISOdate或修改为总是有三毫秒的地方的ISOdate( 见上文 ),所以代码根据环境的不同而不同。
4a)parsing标准的ISOdate格式,应付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 ym-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)以固定的三毫秒小数位parsingISO格式 – 更容易:
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); }
下面这个旧的答案对于把这个date格式绑定到jQuery自己的JSONparsing中很有用,所以你得到Date对象而不是string,或者如果你仍然陷在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调用中的转换器选项来全局覆盖parseJSON
方法。
http://api.jquery.com/jQuery.ajax/
不幸的是,您必须切换到较旧的eval路由才能使date在全局就地parsing – 否则您需要在更大的个案基础上将其转换为后parsing。
我最终将“字符添加到Panos的正则expression式中,以便在将对象写入内联脚本时去除由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); }
JSON中没有内置的datetypes。 这看起来像某个时代的秒/毫秒数。 如果你知道这个纪元,你可以通过添加适当的时间来创builddate。
我也不得不寻找一个解决这个问题的方法,最终我遇到了一个很好的库,可以parsing这个date格式的moment.js等等。
var d = moment(yourdatestring)
它为我节省了一些头痛,所以我想我会分享给你。 🙂
你可以在这里find更多关于它的信息: http : //momentjs.com/
在jQuery 1.5中,只要有json2.js覆盖较旧的浏览器,就可以反序列化来自Ajax的所有date,如下所示:
(function () { var DATE_START = "/Date("; var DATE_START_LENGTH = DATE_START.length; function isDateString(x) { return typeof x === "string" && x.startsWith(DATE_START); } function deserializeDateString(dateString) { var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH))); var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000); return utcDate; } function convertJSONDates(key, value) { if (isDateString(value)) { return deserializeDateString(value); } return value; } window.jQuery.ajaxSetup({ converters: { "text json": function(data) { return window.JSON.parse(data, convertJSONDates); } } }); }());
我包括逻辑,假设你发送所有date从服务器作为UTC(你应该); 消费者然后得到一个具有适当滴答值的JavaScript Date
对象来反映这一点。 也就是说,在date中调用getUTCHours()
等将返回与服务器上相同的值,调用getHours()
将返回用户本地时区中由浏览器确定的值。
这不考虑WCF格式与时区偏移,虽然这将是相对容易添加。
不要过分想这个。 就像我们已经做了几十年一样,从1970年1月1日午夜GMT / UTC /&c以秒数(或毫秒)开始的实际标准时代,传递一个数字偏移。 JavaScript喜欢它,Java喜欢它,C喜欢它,而Internet喜欢它。
这些答案的每个人都有一个共同点:他们都将date存储为一个单一的值(通常是一个string)。
另一种select是利用JSON的固有结构,并将数字表示为数字列表:
{ "name":"Nick", "birthdate":[1968,6,9] }
当然,你必须确保对话的两端同意格式(年,月,日),以及哪些字段是date,但是它的优点是完全避免了date问题string转换。 这是所有的数字 – 根本没有string。 此外,使用顺序:年,月,日也允许按date进行正确sorting。
只是在这里的框外思考 – 一个JSONdate不必存储为一个string。
这样做的另一个好处是,您可以通过利用CouchDB处理数组值的查询的方式,轻松(有效)地select给定年份或月份的所有logging。
使用jQuery UI datepicker – 如果你已经包含了jQuery UI,那么真的很有意义:
$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6))));
输出:
2008年10月15日
张贴在真棒线程:
var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2))); alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
有没有使用jQuery库的另一种select?
只是在这里添加另一种方法,如果你不是非常小心的话,那么WCF所用的“ticks方法”就很容易出现时区问题,例如这里和其他地方所描述的。 所以我现在正在使用.NET和JavaScript正式支持的包含时区偏移的ISO 8601格式。 以下是详细信息:
在WCF / .NET中:
CreationDate是一个System.DateTime; ToString(“o”)使用.NET的往返格式说明符来生成ISO 8601兼容的datestring
new MyInfo { CreationDate = r.CreationDate.ToString("o"), };
在JavaScript中
就在检索到JSON之后,我使用Date构造函数将date修改为JavaSript Date对象,该构造函数接受ISO 8601datestring…
$.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()); } )
一旦你有一个JavaScriptdate,你可以使用所有方便和可靠的date方法,如toDateString , toLocaleString等
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')'); var dateValue = obj["Date"];
检查dateISO标准; 有点像这样:
yyyy.MM.ddThh:mm
变成2008.11.20T22:18
。
我得到这样的date:
"/Date(1276290000000+0300)/"
在一些例子中,date的格式稍有不同:
"/Date(12762900000000300)/" "Date(1276290000000-0300)"
等等
所以我想出了以下RegExp:
/\/+Date\(([\d+]+)\)\/+/
最终的代码是:
var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));
希望它有帮助。
更新:我发现这个链接从微软: 我如何序列化date与JSON?
这似乎是我们都在寻找的一个。
这令人沮丧。 我的解决scheme是从ASP.NET的JavaScriptSerializer生成的值中parsing出“/和/”,这样虽然JSON可能没有date字面量,但它仍然被浏览器解释为date,这就是我所知want: {"myDate":Date(123456789)}
为DateTime定制JavaScriptConverter?
我必须强调Roy Tinker的评论的准确性。 这不是合法的JSON。 这是一个肮脏的,肮脏的黑客在服务器上,以消除这个问题之前,它成为一个问题的JavaScript。 它会窒息一个JSONparsing器。 我用它来起飞,但我不再使用这个。 然而,我仍然觉得最好的答案在于改变服务器如何格式化date,例如,ISO在其他地方提到。
下面是parsingJSONdate的一个非常简单的解决scheme。 根据您的要求使用以下function。 你只需要将JSON格式的Date作为parameter passing给下面的函数:
function JSONDate(dateStr) { var m, day; jsonDate = dateStr; var d = new Date(parseInt(jsonDate.substr(6))); m = d.getMonth() + 1; if (m < 10) m = '0' + m if (d.getDate() < 10) day = '0' + d.getDate() else day = d.getDate(); return (m + '/' + day + '/' + d.getFullYear()) } function JSONDateWithTime(dateStr) { jsonDate = dateStr; var d = new Date(parseInt(jsonDate.substr(6))); var m, day; m = d.getMonth() + 1; if (m < 10) m = '0' + m if (d.getDate() < 10) day = '0' + d.getDate() else day = d.getDate(); var formattedDate = m + "/" + day + "/" + d.getFullYear(); var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours(); var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes(); var formattedTime = hours + ":" + minutes + ":" + d.getSeconds(); formattedDate = formattedDate + " " + formattedTime; return formattedDate; }
一个后期,但对于那些search这个职位。
想象一下:
[Authorize(Roles = "Administrator")] [Authorize(Roles = "Director")] [Authorize(Roles = "Human Resources")] [HttpGet] public ActionResult GetUserData(string UserIdGuidKey) { if (UserIdGuidKey!= null) { var guidUserId = new Guid(UserIdGuidKey); var memuser = Membership.GetUser(guidUserId); var profileuser = Profile.GetUserProfile(memuser.UserName); var list = new { UserName = memuser.UserName, Email = memuser.Email , IsApproved = memuser.IsApproved.ToString() , IsLockedOut = memuser.IsLockedOut.ToString() , LastLockoutDate = memuser.LastLockoutDate.ToString() , CreationDate = memuser.CreationDate.ToString() , LastLoginDate = memuser.LastLoginDate.ToString() , LastActivityDate = memuser.LastActivityDate.ToString() , LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() , IsOnline = memuser.IsOnline.ToString() , FirstName = profileuser.FirstName , LastName = profileuser.LastName , NickName = profileuser.NickName , BirthDate = profileuser.BirthDate.ToString() , }; return Json(list, JsonRequestBehavior.AllowGet); } return Redirect("Index"); }
正如你所看到的,我正在利用C#3.0的function来创build“自动”generics。 这有点懒,但我喜欢它,它的工作原理。 只是一个说明:configuration文件是我为我的Web应用程序项目创build的自定义类。
Mootools解决scheme:
new Date(Date(result.AppendDts)).format('%x')
需要mootools-more。 在Firefox 3.6.3和IE 7.0.5730.13上使用mootools-1.2.3.1-more进行testing
在页面中添加jQuery UI插件:
function DateFormate(dateConvert) { return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1))); };
仅供参考,对于在服务器端使用Python的人:datetime.datetime()。ctime()返回一个string,可以通过“new Date()”本地parsing。 也就是说,如果您创build了一个新的datetime.datetime实例(例如datetime.datetime.now),则可以将该string包含在JSONstring中,然后可以将该string作为第一个parameter passing给Date构造函数。 我还没有发现任何exception,但我也没有太严格地testing过。
您也可以使用JavaScript库moment.js ,它在计划时派上用场,处理不同的本地化格式,并使用date值执行其他操作:
function getMismatch(id) { $.getJSON("Main.aspx?Callback=GetMismatch", { MismatchId: id }, function (result) { $("#AuthMerchId").text(result.AuthorizationMerchantId); $("#SttlMerchId").text(result.SettlementMerchantId); $("#CreateDate").text(moment(result.AppendDts).format("L")); $("#ExpireDate").text(moment(result.ExpiresDts).format("L")); $("#LastUpdate").text(moment(result.LastUpdateDts).format("L")); $("#LastUpdatedBy").text(result.LastUpdateNt); $("#ProcessIn").text(result.ProcessIn); } ); return false; }
设置本地化就像在您的项目中添加configuration文件(您可以在momentjs.com获得它们)并configuration语言一样简单:
moment.lang('de');
如果.NET返回什么…
return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"
然后在JavaScript中…
var x = new Date("2013-09-17 15:18:53Z");
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(); }