如何格式化Microsoft JSON日期?

2020/10/26 01:43 · jquery ·  · 0评论

我正在使用jQueryAjax上进行首次尝试。我正在将数据获取到页面上,但是为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;
}

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

eval()没有必要。这将正常工作:

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

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


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

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

For ISO-8601 formatted JSON dates, just pass the string into the Date constructor:

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)来根据需要显示它。

For those using Newtonsoft Json.NET, read up on how to do it via Native JSON in IE8, Firefox 3.5 plus Json.NET.

Also the documentation on changing the format of dates written by Json.NET is useful:
Serializing Dates with Json.NET

For those that are too lazy, here are the quick steps. As JSON has a loose DateTime implementation, you need to use the IsoDateTimeConverter(). Note that since Json.NET 4.5 the default date format is ISO so the code below isn't needed.

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

The JSON will come through as

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

Finally, some JavaScript to convert the ISO date to a JavaScript date:

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

I used it like this

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

The original example:

/Date(1224043200000)/  

does not reflect the formatting used by WCF when sending dates via WCF REST using the built-in JSON serialization. (at least on .NET 3.5, SP1)

I found the answer here helpful, but a slight edit to the regex is required, as it appears that the timezone GMT offset is being appended onto the number returned (since 1970) in WCF JSON.

In a WCF service I have:

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

ApptVisitLinkInfo is defined simply:

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

When "Field2" is returned as Json from the service the value is:

/Date(1224043200000-0600)/

Notice the timezone offset included as part of the value.

The modified regex:

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

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

用于替换的JavaScript代码如下:

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

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

帖子的答案提供了将日期手动转换为JavaScript日期的功能。$.parseJSON()扩展了jQuery的一点,因此它能够在您指示时自动解析日期。它处理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)/最初在此处询问)以及大多数JSON的日期格式(包括JSON.NET)的要求2014-06-22T00:00:00.0此外,我们需要应对oldIE无法处理的任何其他问题(小数点后3位)

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

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中,可以parseJSON通过使用Ajax调用中的converters选项避免全局重写该方法。

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

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

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

我还必须搜索该问题的解决方案,最终我遇到了moment.js,这是一个不错的库,可以解析此日期格式等等。

var d = moment(yourdatestring)

它为我省去了一些麻烦,所以我想与您分享。:)

您可以在这里找到有关它的更多信息:
http :
//momentjs.com/

我最终在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);
}

在jQuery 1.5中,只要您有json2.js可以覆盖较旧的浏览器,就可以反序列化来自Ajax的所有日期,如下所示:

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

我包含了一个逻辑,该逻辑假定您将服务器中的所有日期作为UTC发送(应该这样做);消费者然后获得一个JavaScriptDate对象,该对象具有适当的ticks值来反映这一点。也就是说,getUTCHours()在日期上调用,等将返回与服务器上相同的值,并且调用getHours()将在用户的本地时区(由其浏览器确定)中返回该值。

尽管这相对容易添加,但这并未考虑到带有时区偏移的WCF格式。

使用jQuery UI datepicker-仅当您已经包含jQuery UI时才有意义:

$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6)))); 

输出:

2008年10月15日

不要想太多。就像我们数十年来所做的那样,传递距实际时间1970年1月1日午夜GMT / UTC /&c的标准时间段的数字偏移量,以秒为单位(秒)。JavaScript喜欢它,Java喜欢它,C喜欢它,而Internet喜欢它。

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

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

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

当然,您必须确保对话的两端在格式(年,月,日)上以及哪个字段应为日期方面达成共识,但是它的优点是完全避免了日期问题到字符串的转换。全部都是数字-完全没有字符串。另外,使用顺序:年,月,日还可以按日期正确排序。

只是想在这里跳出框框-JSON日期不必存储为字符串。

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

在真棒线程中发布:

var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));

仅在此处添加另一种方法,如果您不十分小心WCF采取的“滴答方法”就容易出现时区问题,例如此处所述和其他地方因此,我现在使用的是.NET和JavaScript都适当支持的ISO 8601格式,其中包括时区偏移量。以下是详细信息:

在WCF / .NET中:

其中CreationDate是System.DateTime;ToString(“ o”)使用.NET的往返格式说明符,该说明符生成符合ISO 8601的日期字符串

new MyInfo {
    CreationDate = r.CreationDate.ToString("o"),
};

在JavaScript中

刚获取JSON之后,我就使用Date构造函数将日期固定为JavaSript Date对象,该构造函数接受ISO 8601日期字符串...

$.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方法,例如toDateStringtoLocaleString等。

var newDate = dateFormat(jsonDate, "mm/dd/yyyy"); 

有没有不使用jQuery库的另一种选择?

这也可以为您提供帮助。

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

我得到这样的日期:

"/Date(1276290000000+0300)/"

在某些示例中,日期格式略有不同:

"/Date(12762900000000300)/"
"Date(1276290000000-0300)"

等等

所以我想出了以下RegExp:

/\/+Date\(([\d+]+)\)\/+/

最终的代码是:

var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));

希望能帮助到你。

更新:我从Microsoft找到了此链接:
如何使用JSON序列化日期?

这似乎是我们都在寻找的那个。

以下是解析JSON日期的非常简单的解决方案。根据需要使用以下功能。您只需要将获取的JSON格式Date作为参数传递给以下函数:

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

您还可以使用JavaScript库moment.js,当您计划处理不同的本地化格式并执行带有日期值的其他操作时,该非常有用:

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

设置本地化就像向您的项目中添加配置文件(您可以在momentjs.com上获取它们)并配置语言一样简单:

moment.lang('de');

检查日期ISO标准;有点像这样:

yyyy.MM.ddThh:mm

它变成了2008.11.20T22:18

这真令人沮丧。我的解决方案是从ASP.NET的JavaScriptSerializer生成的值中解析出“ /和/”,这样,尽管JSON可能没有日期文字,但浏览器仍将其解释为日期,这就是我真正想要的。想:{"myDate":Date(123456789)}

是否为DateTime自定义JavaScriptConverter?

我必须强调罗伊·廷克(Roy Tinker)评论的准确性。这不是合法的JSON。在JavaScript成为问题之前,删除服务器上的问题是一种肮脏的,肮脏的黑客行为。它将阻塞JSON解析器。我用它来起步,但是我不再使用它了。但是,我仍然认为最好的答案是更改服务器格式化日期的方式,例如,其他地方提到的ISO。

较晚的帖子,但适用于搜索该帖子的用户。

想象一下:

    [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的功能来创建“自动”泛型。有点懒,但是我喜欢它并且可以用。请注意:Profile是我为Web应用程序项目创建的自定义类。

仅供参考,对于在服务器端使用Python的任何人:datetime.datetime()。ctime()返回一个可通过“ new Date()”本地解析的字符串。也就是说,如果创建一个新的datetime.datetime实例(例如使用datetime.datetime.now),则可以将该字符串包含在JSON字符串中,然后可以将该字符串作为第一个参数传递给Date构造函数。我还没有发现任何例外,但是我也没有进行过严格的测试。

Mootools解决方案:

new Date(Date(result.AppendDts)).format('%x')

需要更多的mootools。已在Firefox 3.6.3和IE 7.0.5730.13上使用mootools-1.2.3.1-more测试

var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];

在页面中添加jQuery UI插件:

function DateFormate(dateConvert) {
    return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};

如果.NET返回...

return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"

然后在JavaScript中...

var x = new Date("2013-09-17 15:18:53Z");
本文地址:http://jquery.askforanswer.com/ruhegeshihuamicrosoft-jsonriqi.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!