[Jquery] 如何格式化Microsoft JSON日期?



Answers

你可以用它從JSON獲取日期:

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

然後,您可以使用JavaScript日期格式腳本(縮小和壓縮後為1.2 KB)來按需要顯示它。

Question

我正在使用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;
}

該解決方案從回調方法中獲得了我的對象,並使用日期格式庫正確顯示了頁面上的日期。




更新

我們有一個內部的用戶界面庫,它必須同時處理微軟的ASP.NET內置的JSON格式,如/Date(msecs)/ ,最初問到這裡,以及大多數JSON的日期格式,包括JSON.NET,比如2014-06-22T00:00:00.0 。 另外,我們需要處理oldIE無法處理除小數點後三位的任何事情 。

我們首先檢測我們正在使用的日期類型,將其解析為正常的JavaScript Date對象,然後將其格式化。

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日期或修改為始終有三毫秒的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中,您可以避免使用Ajax調用中的轉換器選項來全局覆蓋parseJSON方法。

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

不幸的是,您必須切換到較舊的eval路由才能使日期在全局就地解析 - 否則您需要在更大的個案基礎解析後轉換它們。




只是在這裡添加另一種方法,如果您沒有特別小心,例如here和其他地方所述的WCF採用的“ticks方法”,則容易出現時區問題。 所以我現在使用的是ISO 8601格式,.NET和JavaScript正式支持包括時區偏移。 以下是詳細信息:

在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日期,你可以使用所有方便可靠的日期方法,如toDateStringtoLocaleString等。




張貼在真棒線程:

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



最初的例子:

/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

它稍微更熱切,並且抓住了所有人之間的一切,而不僅僅是第一個數字。 結果1970年的時間,再加上時區偏移量都可以輸入到eval中以獲取日期對象。

用於替換的JavaScript結果行是:

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



在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(您應該); 然後消費者獲取具有適當滴答值的JavaScript Date對象來反映這一點。 也就是說,在日期中調用getUTCHours()等將返回與服務器上相同的值,並且調用getHours()將返回用戶本地時區中由其瀏覽器確定的值。

這不考慮帶時區偏移的WCF格式,儘管這樣做相對容易添加。




這令人沮喪。 我的解決方案是從ASP.NET的JavaScriptSerializer生成的值中解析出“/和/”,這樣雖然JSON可能沒有日期字面值,但它仍然被瀏覽器解釋為日期,這就是我真正所知want: {"myDate":Date(123456789)}

為DateTime定制JavaScriptConverter?

我必須強調Roy Tinker的評論的準確性。 這不是合法的JSON。 這是一個骯髒,骯髒的黑客攻擊服務器上的問題,以解決問題之前,它成為一個JavaScript問題。 它會阻塞JSON解析器。 我用它來起飛,但我不再使用它。 不過,我仍然覺得最好的答案在於改變服務器如何格式化日期,例如,如其他地方提到的ISO。




Mootools解決方案:

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

需要mootools-more。 在Firefox 3.6.3和IE 7.0.5730.13上使用mootools-1.2.3.1-more進行測試




僅供參考,對於在服務器端使用Python的任何人:datetime.datetime()。ctime()返回一個字符串,可以通過“new Date()”本地解析。 也就是說,如果您創建了一個新的datetime.datetime實例(例如datetime.datetime.now),則可以將該字符串包含在JSON字符串中,然後可以將該字符串作為第一個參數傳遞給Date構造函數。 我還沒有發現任何異常,但我還沒有太嚴格地測試過它。




檢查日期ISO標準; 有點像這樣:

yyyy.MM.ddThh:mm

它變成2008.11.20T22:18




下面是解析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;
}



使用jQuery UI日期選擇器 - 如果你已經包含jQuery UI,那麼它真的很有意義:

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

輸出:

2008年10月15日




這可能也可以幫助你。

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



我最終將“字符添加到Panos的正則表達式中,以便在將對象寫入內聯腳本時擺脫由Microsoft序列化程序生成的字符:

所以如果你在你的C# code-behind有一個屬性,就像是

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

我使用Prototype並使用它,我補充說

String.prototype.evalJSONWithDates = function() {
    var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
    return jsonWithDates.evalJSON(true);
}



如果你用JavaScript說,

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

你會發現它是正確的日期,並且你可以在任何地方使用任何框架的JavaScript代碼。




Links