JS jQuery json日期格式問題的辦法


原生JS:Date對象詳細參考

Date對象:基於1970年1月1日(世界標准時間)起的毫秒數

本文參考MDN做的詳細整理,方便大家參考MDN

構造函數:

  1. new Date(); 依據系統設置的當前時間來創建一個Date對象。
  2. new Date(value); value代表自1970年1月1日00:00:00 (世界標准時間) 起經過的毫秒數。
  3. new Date(dateString); dateString表示日期的字符串值。該字符串應該能被 Date.parse() 方法識別(符合 IETF-compliant RFC 2822 timestamps 或 version of ISO8601)
  4. new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
    year 1900 年后的某一年份,代表年份的整數值。為了避免2000年問題最好指定4位數的年份; 使用 1998, 而不要用 98.
    month 0 到 11 之間的一個整數,表示月份(1月)到11(12月)。
    day 1 到 31 之間的一個整數,表示某月當中的第幾天。
    hour 0 到 23 之間的一個整數,表示小時。
    minute 0 到 59 之間的一個整數,表示分鍾。。
    second 0 到 59 之間的一個整數,秒數。
    millisecond 0 到 999 之間的一個整數,表示時間的毫秒部分的整數值。

如果提供了至少兩個參數,其余的參數均會默認設置為1(如果沒有提供day參數)或者0。

JavaScript的時間是由世界標准時間(UTC)1970年1月1日開始,用毫秒計時,一天由86,400,000毫秒組成。Date對象的范圍是-100,000,000天至100,000,000天(等效的毫秒值)。

JavaScript的Date對象為跨平台提供了統一的行為。時間屬性可以在不同的系統中表示相同的時刻,而如果使用了本地時間對象,則反映當地的時間。

JavaScript 的Date對象提供了數個UTC時間的方法,也相應提供了當地時間的方法。UTC,也就是我們所說的格林威治時間,指的是time中的世界時間標准。而當地時間則是指執行JavaScript的客戶端電腦所設置的時間。

以一個函數的形式來調用JavaScript的Date對象(不使用 new 操作符)會返回一個代表當前日期和時間的字符串。而不是一個日期對象。另外,不像其他JavaScript 類型,Date 對象沒有字面量格式。

當Date作為構造函數調用並傳入多個參數時,如果數值大於合理范圍時(如月份為13或者分鍾數為70),相鄰的數值會被調整。比如 new Date(2013, 13, 1)等於new Date(2014, 1, 1),它們都表示日期2014-02-01(注意月份是從0開始的)。其他數值也是類似,new Date(2013, 2, 1, 0, 70)等於new Date(2013, 2, 1, 1, 10),都表示時間2013-03-01T01:10:00。

當Date作為構造函數調用並傳入多個參數時,所定義參數代表的是當地時間。如果需要世界協調時,使用 new Date({{jsxref("Date.UTC()", "Date.UTC(...)")}}) 和相同參數

屬性:

Date.prototype :允許為 Date 實例對象添加屬性。
Date.length:值是 7。這是該構造函數可接受的參數個數。

Date靜態方法:

Date.now() IE9

返回自 1970-1-1 00:00:00 UTC (時間標准時間)至今所經過的毫秒數,類型為Number。
在支持 Web Performance API 的高精細度(high-resolution)時間功能的瀏覽器中,window.performance.now 提供的所經過的時間比 Date.now 更可靠和精確。
兼容舊版瀏覽器:

if (!Date.now) {
  Date.now = function now() {
    return new Date().getTime();
  };
}
Date.parse()

解析一個表示日期的字符串,並返回從 1970-1-1 00:00:00 所經過的毫秒數。如果參數不能解析為一個有效的日期,則返回NaN。
parse 方法接受一個日期字符串(例如 "Dec 25, 1995"),並返回從1970-1-1 00:00:00 UTC到該日期字符串所表示日期的毫秒數。該方法在基於字符串值設置日期值時很有用,例如結合使用setTime() 方法和 Date() 構造函數。
該方法可以接受符合 RFC2822 / IETF 日期語法 (RFC2822 Section 3.3) 的字符串,如 "Mon, 25 Dec 1995 13:30:00 GMT"。該方法能夠理解美國大陸時區的縮寫,但是為了更通用,應該使用時區偏移,如 "Mon, 25 Dec 1995 13:30:00 +0430" (格林威治的子午線向東偏移4小時30分鍾)。如果沒有指定時區,默認使用本地時區。
GMT 和 UTC 被看作相等。 如果 RFC2822 Section 3.3 格式中不包含時區信息時,會以本地時區來解析日期字符串。
由於在解析日期字符串時存在偏差會導致結果不一致,因此推薦始終手動解析日期字符串,特別是不同的ECMAScript實現會把諸如“2015-10-12 12:00:00”的字符串解析為NaN,UTC或者本地時間。
另外,日期時間字符串也可以使用 ISO 8601 格式。例如,"2011-10-10" (僅日期)或 "2011-10-10T14:48:00" (日期和時間)能夠作為參數被傳遞和解析

Date.UTC()

接受和構造函數最長形式的參數相同的參數(從2到7),並返回從 1970-01-01 00:00:00 UTC 開始所經過的毫秒數,類型為Number。
你應該指定一個完整格式的年份,如 1998
Date.UTC 方法使用協調世界時 代替 本地時間。
Date.UTC 方法返回一個時間數值,而不是一個日期對象。
如果有一個指定的參數超出其合理范圍,則 UTC 方法會通過更新其他參數直到該參數在合理范圍內。例如,為月份指定 15,則年份將會加 1,然后月份將會使用 3。

Date 實例方法:

根據本地時間的方法
獲取時間方法:

Date.prototype.getDate()
根據本地時間返回指定日期對象的月份中的第幾天(1-31)。
Date.prototype.getDay()
根據本地時間返回指定日期對象的星期中的第幾天(0-6)。
Date.prototype.getFullYear()
根據本地時間返回指定日期對象的年份,該方法返回一個1000 到 9999的四位數字年份,請使用該方法代替 getYear 方法。
Date.prototype.getHours()
根據本地時間返回指定日期對象的小時(0-23)。
Date.prototype.getMilliseconds()
根據本地時間返回指定日期對象的微秒(0-999)。
Date.prototype.getMinutes()
根據本地時間返回指定日期對象的分鍾(0-59)。
Date.prototype.getMonth()
根據本地時間返回指定日期對象的月份(0-11)。
Date.prototype.getSeconds()
根據本地時間返回指定日期對象的秒數(0-59)。
Date.prototype.getTime()
返回從1970-1-1 00:00:00 UTC(協調世界時)到該日期經過的毫秒數,Number類型,對於1970-1-1 00:00:00 UTC之前的時間返回負值。這個方法的功能和 valueOf() 方法一樣。
Date.prototype.getTimezoneOffset()
返回協調世界時(UTC)相對於當前時區的時間差值,單位為分鍾。
時區偏差(time-zone offset)表示協調世界時(UTC)與本地時區之間的差值,單位為分鍾。需要注意的是如果本地時區晚於協調世界時,則該差值為正值,如果早於協調世界時則為負值

設置時間方法:以下方法如果有一個參數超出了合理的范圍,該方法會更新其他參數值,日期對象的日期值也會被相應更新

Date.prototype.setDate(value)
根據本地時間為指定的日期對象設置月份中的第幾天。
如果 value 超出了月份的合理范圍,setDate 將會相應地更新 Date 對象。例如,如果為 value 指定0,那么日期就會被設置為上個月的最后一天,可以為負數。
Date.prototype.setFullYear(yearValue[, monthValue[, dayValue]])
根據本地時間為指定日期對象設置完整年份(四位數年份是四個數字)。
yearValue指定年份的整數值,例如1995。
monthValue一個0到11之間的整數值,表示從一月到十二月。
dayValue一個1到31之間的整數值,表示月份中的第幾天。如果你指定了 dayValue 參數,就必須同時指定 monthValue。
如果沒有指定 monthValue 和dayValue 參數,將會使用 getMonth 和getDate 方法的返回值
Date.prototype.setHours(hoursValue[, minutesValue[, secondsValue[, msValue]]])
根據本地時間為指定日期對象設置小時數。如果不指定 minutesValue,secondsValue 和 msValue 參數,則會使用getMinutes(),getSeconds() 和getMilliseconds() 方法的返回值。
參數超出了合理范圍,自動調整更新
Date.prototype.setMilliseconds()
根據本地時間為指定日期對象設置毫秒數。
Date.prototype.setMinutes()
根據本地時間為指定日期對象設置分鍾數。
Date.prototype.setMonth()
根據本地時間為指定日期對象設置月份。
Date.prototype.setSeconds()
根據本地時間為指定日期對象設置秒數。
Date.prototype.setTime(timeValue)
通過指定從 1970-1-1 00:00:00 UTC 開始經過的毫秒數來設置日期對象的時間,對於早於 1970-1-1 00:00:00 UTC的時間可使用負值。例:sameBigDay.setTime(newBigDay.getTime());

以世界時為標准的方法:

Date.prototype.getUTCDate()
以世界時為標准,返回一個指定的日期對象是一個月中的第幾天,返回 1 到 31 的整數值
Date.prototype.getUTCDay()
以世界時為標准,返回一個指定的日期對象為一星期中的第幾天,其中 0 代表星期天。
Date.prototype.getUTCFullYear()
以世界時為標准,返回一個指定的日期對象的年份,該方法返回一個1000 到 9999的四位數字年份
Date.prototype.getUTCHours()
以世界時為標准,返回一個指定的日期對象的小時數。
Date.prototype.getUTCMilliseconds()
以世界時為標准,返回一個指定的日期對象的毫秒數。.
Date.prototype.getUTCMinutes()
以世界時為標准,返回一個指定的日期對象的分鍾數.
Date.prototype.getUTCMonth()
以世界時為標准,返回一個指定的日期對象的月份,它是從 0 開始計數的(0 代表一年的第一個月).
Date.prototype.getUTCSeconds()
以世界時為標准,返回一個指定的日期對象的秒數.
Date.prototype.setUTCDate()
根據世界時設置 Date 對象中月份的一天 (1 ~ 31)。
Date.prototype.setUTCFullYear()
根據世界時設置 Date 對象中的年份(四位數字)。
Date.prototype.setUTCHours()
根據世界時設置 Date 對象中的小時 (0 ~ 23)。
Date.prototype.setUTCMilliseconds()
根據世界時設置 Date 對象中的毫秒 (0 ~ 999)。
Date.prototype.setUTCMinutes()
根據世界時設置 Date 對象中的分鍾 (0 ~ 59)。
Date.prototype.setUTCMonth()
根據世界時設置 Date 對象中的月份 (0 ~ 11)。
Date.prototype.setUTCSeconds()
根據世界時設置 Date 對象中的秒鍾 (0 ~ 59)

日期格式轉換:

Date.prototype.toDateString()
以人類易讀(human-readable)的形式返回該日期對象日期部分的字符串。
Date.prototype.toISOString() IE9
返回一個 ISO(ISO 8601 Extended Format)格式的字符串: YYYY-MM-DDTHH:mm:ss.sssZ。時區總是UTC(協調世界時),加一個后綴“Z”標識
Date.prototype.toJSON()
返回一個 JSON 格式字符串(使用 toISOString()),表示該日期對象的值。默認情況下,這個方法常用於 JSON序列化Date對象。。為了在 JSON.stringify() 方法中使用。
Date.prototype.toLocaleDateString()
返回一個表示該日期對象日期部分的字符串,該字符串格式與系統設置的地區關聯(locality sensitive)。其它同toLocaleTimeString()
Date.prototype.toLocaleString()
返回一個表示該日期對象的字符串,該字符串與系統設置的地區關聯。覆蓋了 Object.prototype.toLocaleString() 方法。其它同toLocaleTimeString()
Date.prototype.toLocaleTimeString([locales [, options]])
返回一個表示該日期對象時間部分的字符串,該字符串格式與系統設置的地區關聯(locality sensitive)。
方法返回該日期對象日期部分的字符串,該字符串格式因不同語言而不同。新增的參數(IE11,而Safari無) locales 和 options 使程序能夠指定使用哪種語言格式化規則,允許定制該方法的表現(behavior)。在舊版本瀏覽器中, locales 和 options 參數被忽略,使用的語言環境和返回的字符串格式是各自獨立實現的
查看瀏覽器兼容性小節,看下哪些瀏覽器支持 locales 和 options 參數,還可以參看例子: 檢測 locales 和 options 參數支持情況。
沒有指定語言環境(locale)時,返回一個使用默認語言環境和格式設置(options)的格式化字符串。
locales 和 options 參數不是所有的瀏覽器都支持。為了檢測一種實現環境(implementation)是否支持它們,可以使用不合法的語言標簽,如果實現環境支持該參數,則會拋出一個 RangeError 異常,反之會忽略參數。
性能:當格式化大量日期時,最好創建一個 Intl.DateTimeFormat 對象,然后使用該對象 format 屬性提供的方法。
Date.prototype.toString()
返回一個表示該日期對象的字符串,總是返回一個美式英語日期格式的字符串。覆蓋了Object.prototype.toString() 方法。
Date.prototype.toTimeString()
以人類易讀格式返回日期對象時間部分的字符串。
Date.prototype.toUTCString()
把一個日期對象轉換為一個以UTC時區計時的字符串。
Date.prototype.valueOf()
返回從1970年1月1日0時0分0秒(UTC,即協調世界時)到該日期對象所代表時間的毫秒數。該方法的功能和 Date.prototype.getTime() 方法一樣,覆蓋了 Object.prototype.valueOf() 方法。

 
 
 

4種解決json日期格式問題的辦法

 

開發中有時候需要從服務器端返回json格式的數據,在后台代碼中如果有DateTime類型的數據使用系統自帶的工具類序列化后將得到一個很長的數字表示日期數據,如下所示:

           //設置服務器響應的結果為純文本格式
            context.Response.ContentType = "text/plain";
           //學生對象集合
            List<Student> students = new List<Student>
            {
                new Student(){Name ="Tom",
                    Birthday =Convert.ToDateTime("2014-01-31 12:12:12")},
                new Student(){Name ="Rose",
                    Birthday =Convert.ToDateTime("2014-01-10 11:12:12")},
                new Student(){Name ="Mark",
                    Birthday =Convert.ToDateTime("2014-01-09 10:12:12")}
            };

            //javascript序列化器
            JavaScriptSerializer jss=new JavaScriptSerializer();
           //序列化學生集合對象得到json字符
            string studentsJson=jss.Serialize(students);
           //將字符串響應到客戶端
            context.Response.Write(studentsJson);
           context.Response.End();

運行結果是:

其中Tom所對應生日“2014-01-31”變成了1391141532000,這其實是1970 年 1 月 1 日至今的毫秒數;1391141532000/1000/60/60/24/365=44.11年,44+1970=2014年,按這種方法可以得出年月日時分秒和毫秒。這種格式是一種可行的表示形式但不是普通人可以看懂的友好格式,怎么讓這個格式變化?

解決辦法:

方法1:在服務器端將日期格式使用Select方法或LINQ表達式轉換后發到客戶端:

using System;
using System.Collections.Generic;
using System.Web;

using System.Web.Script.Serialization;

namespace JsonDate1
{
    using System.Linq;

    /// <summary>
    /// 學生類,測試用
    /// </summary>
    public class Student
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public String Name { get; set; }

        /// <summary>
        /// 生日
        /// </summary>
        public DateTime Birthday { get; set; }
    }

    /// <summary>
    /// 返回學生集合的json字符
    /// </summary>
    public class GetJson : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //設置服務器響應的結果為純文本格式
            context.Response.ContentType = "text/plain";
            //學生對象集合
            List<Student> students = new List<Student>
            {
                new Student(){Name ="Tom",Birthday =Convert.ToDateTime("2014-01-31 12:12:12")},
                new Student(){Name ="Rose",Birthday =Convert.ToDateTime("2014-01-10 11:12:12")},
                new Student(){Name ="Mark",Birthday =Convert.ToDateTime("2014-01-09 10:12:12")}
            };

            //使用Select方法重新投影對象集合將Birthday屬性轉換成一個新的屬性
            //注意屬性變化后要重新命名,並立即執行
            var studentSet =
                students.Select
                (
                p => new { p.Name, Birthday = p.Birthday.ToString("yyyy-mm-dd") }
                ).ToList();

            //javascript序列化器
            JavaScriptSerializer jss = new JavaScriptSerializer();
            //序列化學生集合對象得到json字符
            string studentsJson = jss.Serialize(studentSet);
            //將字符串響應到客戶端
            context.Response.Write(studentsJson);
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

Select方法重新投影對象集合將Birthday屬性轉換成一個新的屬性,注意屬性變化后要重新命名,屬性名可以相同;這里可以使用select方法也可以使用LINQ查詢表達式,也可以選擇別的方式達到相同的目的;這種辦法可以將集合中客戶端不用的屬性剔除,達到簡單優化性能的目的。

運行結果:

這時候的日期格式就已經變成友好格式了,不過在javascript中這只是一個字符串。

方法二:

在javascript中將"Birthday":"\/Date(1391141532000)\/"中的字符串轉換成javascript中的日期對象,可以將Birthday這個Key所對應的Value中的非數字字符以替換的方式刪除,到到一個數字1391141532000,然后實例化一個Date對象,將1391141532000毫秒作為參數,得到一個javascript中的日期對象,代碼如下:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>json日期格式處理</title>
    <script src="Scripts/jquery-1.10.2.min.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(function() {
            $.getJSON("getJson.ashx", function (students) {
                $.each(students, function (index, obj) {
                    $("<li/>").html(obj.Name).appendTo("#ulStudents");

                    //使用正則表達式將生日屬性中的非數字(\D)刪除
                    //並把得到的毫秒數轉換成數字類型
                    var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, ""));
                    //實例化一個新的日期格式,使用1970 年 1 月 1 日至今的毫秒數為參數
                    var birthday = new Date(birthdayMilliseconds);

                    $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents"); ;
                });
            });
        });
    </script>
</head>
<body>
    <h2>json日期格式處理</h2>
    <ul id="ulStudents">
    </ul>
</body>
</html>

運行結果:

上的使用正則/\D/igm達到替換所有非數字的目的,\D表示非數字,igm是參數,分別表示忽視(ignore)大小寫;多次、全局(global)替換;多行替換(multi-line);有一些時候還會出現+86的情況,只需要變換正則同樣可以達到目的。另外如果項目中反復出現這種需要處理日期格式的問題,可以擴展一個javascript方法,代碼如下:

$(function () {
            $.getJSON("getJson.ashx", function (students) {
                $.each(students, function (index, obj) {
                  $("<li/>").html(obj.Name).appendTo("#ulStudents");

                  //使用正則表達式將生日屬性中的非數字(\D)刪除
                    //並把得到的毫秒數轉換成數字類型
                    var birthdayMilliseconds = parseInt(obj.Birthday.replace(/\D/igm, ""));
                  //實例化一個新的日期格式,使用1970 年 1 月 1 日至今的毫秒數為參數
                    var birthday = new Date(birthdayMilliseconds);

                  $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents");
                  $("<li/>").html(obj.Birthday.toDate()).appendTo("#ulStudents");
                });
            });
        });

        //在String對象中擴展一個toDate方法,可以根據要求完善
        String.prototype.toDate = function () {
            var dateMilliseconds;
            if (isNaN(this)) {
                //使用正則表達式將日期屬性中的非數字(\D)刪除
                dateMilliseconds =this.replace(/\D/igm, "");
            } else {
                dateMilliseconds=this;
            }
            //實例化一個新的日期格式,使用1970 年 1 月 1 日至今的毫秒數為參數
            return new Date(parseInt(dateMilliseconds));
        };
        

上面擴展的方法toDate不一定合理,也不夠強大,可以根據需要修改。

方法三:

可以選擇一些第三方的json工具類,其中不乏有一些已經對日期格式問題已處理好了的,常見的json序列化與反序列化工具庫有:

1.fastJSON.
2.JSON_checker.
3.Jayrock.
4.Json.NET - LINQ to JSON.
5.LitJSON.
6.JSON for .NET.
7.JsonFx.
8.JSONSharp.
9.JsonExSerializer.
10.fluent-json
11.Manatee Json 

這里以litjson為序列化與反序列化json的工具類作示例,代碼如下:

using System;
using System.Collections.Generic;
using System.Web;

using LitJson;

namespace JsonDate2
{
    using System.Linq;

    /// <summary>
    /// 學生類,測試用
    /// </summary>
    public class Student
    {
        /// <summary>
        /// 姓名
        /// </summary>
        public String Name { get; set; }

        /// <summary>
        /// 生日
        /// </summary>
        public DateTime Birthday { get; set; }
    }

    /// <summary>
    /// 返回學生集合的json字符
    /// </summary>
    public class GetJson : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            //設置服務器響應的結果為純文本格式
            context.Response.ContentType = "text/plain";
            //學生對象集合
            List<Student> students = new List<Student>
            {
                new Student(){Name ="Tom",Birthday =Convert.ToDateTime("2014-01-31 12:12:12")},
                new Student(){Name ="Rose",Birthday =Convert.ToDateTime("2014-01-10 11:12:12")},
                new Student(){Name ="Mark",Birthday =Convert.ToDateTime("2014-01-09 10:12:12")}
            };

            //序列化學生集合對象得到json字符
            string studentsJson = JsonMapper.ToJson(students);
            //將字符串響應到客戶端
            context.Response.Write(studentsJson);
            context.Response.End();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

運行結果如下:

這時候的日期格式就基本正確了,只要在javascript中直接實例化日期就好了,

var date = new Date("01/31/2014 12:12:12");
alert(date.toLocaleString());

客戶端的代碼如下:

$(function () {
            $.getJSON("GetJson2.ashx", function (students) {
                $.each(students, function (index, obj) {
                    $("<li/>").html(obj.Name).appendTo("#ulStudents");

                    var birthday = new Date(obj.Birthday);
                    $("<li/>").html(birthday.toLocaleString()).appendTo("#ulStudents");
                });
            });
        });

        var date = new Date("01/31/2014 12:12:12");
        alert(date.toLocaleString());

方法四:

這點文字發到博客上有網友提出了他們寶貴的意見,我並沒有考慮在MVC中的情況,其實MVC中也可以使用handler,所以區別不是很大了,但MVC中有專門針對服務器響應為JSON的Action,代碼如下:

using System;
using System.Web.Mvc;

namespace JSONDateMVC.Controllers
{
    public class HomeController : Controller
    {
        public JsonResult GetJson1()
        {
            //序列化當前日期與時間對象,並允許客戶端Get請求
            return Json(DateTime.Now, JsonRequestBehavior.AllowGet);
        }
    }
}

運行結果:

下載一個內容為Application/json的文件,文件名為GetJson1,內容是"\/Date(1391418272884)\/"

從上面的情況看來MVC中序列化時並未對日期格式特別處理,我們可以反編譯看源碼:

Return調用的Json方法:

protected internal JsonResult Json(object data, JsonRequestBehavior behavior)
{
    return this.Json(data, null, null, behavior);
}

this.Json方法

protected internal virtual JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
    return new JsonResult { Data = data, ContentType = contentType, ContentEncoding = contentEncoding, JsonRequestBehavior = behavior };
}

JsonResult類ActionResult類的子類,ExecuteResult方法:

從上面的代碼中不難看出微軟的JsonResult類仍然是使用了JavaScriptSerializer,所以返回的結果與方法一未處理時是一樣的,要解決這個問題我們可以派生出一個新的類,重寫ExecuteResult方法,使用Json.net來完成序列化工作,JsonResultPro.cs文件的代碼如下:

namespace JSONDateMVC.Common
{
    using System;
    using System.Web;

    using System.Web.Mvc;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    public class JsonResultPro : JsonResult
    {
        public JsonResultPro(){}
        public JsonResultPro(object data, JsonRequestBehavior behavior)
        {
            base.Data = data;
            base.JsonRequestBehavior = behavior;
            this.DateTimeFormat = "yyyy-MM-dd hh:mm:ss";
        }
        public JsonResultPro(object data, String dateTimeFormat)
        {
            base.Data = data;
            base.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
            this.DateTimeFormat = dateTimeFormat;
        }

        /// <summary>
        /// 日期格式
        /// </summary>
        public string DateTimeFormat{ get; set; }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if ((this.JsonRequestBehavior == JsonRequestBehavior.DenyGet) && string.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
            {                
                throw new InvalidOperationException("MvcResources.JsonRequest_GetNotAllowed");
            }
            HttpResponseBase base2 = context.HttpContext.Response;
            if (!string.IsNullOrEmpty(this.ContentType))
            {
                base2.ContentType = this.ContentType;
            }
            else
            {
                base2.ContentType = "application/json";
            }
            if (this.ContentEncoding != null)
            {
                base2.ContentEncoding = this.ContentEncoding;
            }
            if (this.Data != null)
            {
                //轉換System.DateTime的日期格式到 ISO 8601日期格式
                //ISO 8601 (如2008-04-12T12:53Z)
                IsoDateTimeConverter isoDateTimeConverter=new IsoDateTimeConverter();
                //設置日期格式
                isoDateTimeConverter.DateTimeFormat = DateTimeFormat;
                //序列化
                String jsonResult = JsonConvert.SerializeObject(this.Data,isoDateTimeConverter);
                //相應結果
                base2.Write(jsonResult);
            }

        }
    }
}

使用上面的JsonResultPro Action類型的代碼如下:

        public JsonResultPro GetJson2()
        {
            //序列化當前日期與時間對象,並允許客戶端Get請求,注意H是大寫
            return new JsonResultPro(DateTime.Now,"yyyy-MM-dd HH:mm");
        }

運行結果:

"2014-02-03 18:10"

這樣就可以完全按自己的意思來設置日期格式了,但需要注意日期格式如平時的Format是有區別的,如這里表示時間的H如果大寫表示24小時制,如果小寫表示12小時制。另外還有幾個問題要問大家:

1、通過Reflector反編譯得到的代碼中有很多變化,如屬性會變成get_Request()方法的形式,不知道大家有沒有更好的方法。

2、在反編譯得到的代碼中使用到了資源文件MvcResources.JsonRequest_GetNotAllowed,怎么在重寫時也可以使用?

這里講到了幾種解決json中序列化后的日期格式問題,應該還有更好更完善的方法,歡迎您告訴我。因為有很多學生問我所以我寫了這點文字,歡迎批評指正。

示例代碼下載

MVC示例代碼下載

 
 
 

JSON格式不直接支持日期和時間。DateTime值值顯示為“/Date(700000+0500)/”形式的JSON字符串,其中第一個數字(在提供的示例中為 700000)是 GMT 時區中自 1970 年 1 月 1 日午夜以來按正常時間(非夏令時)經過的毫秒數。該數字可以是負數,以表示之前的時間。示例中包括“+0500”的部分可選,它指示該時間屬於Local類型,即它在反序列化時應轉換為本地時區。如果沒有該部分,則會將時間反序列化為Utc。

     修改Person類,添加LastLoginTime:

序列化結果:

{"Age":28,"LastLoginTime":"//Date(1294499956278+0800)//","Name":"張三"}

     1 、在后台使用正則表達式對其替換處理。修改JsonHelper:

 序列化Demo:

運行結果:

{"Age":28,"LastLoginTime":"2011-01-09 01:00:56","Name":"張三"}

       反序列化Demo:

string json = "{/"Age/":28,/"LastLoginTime/":/"2011-01-09 00:30:00/",/"Name/":/"張三/"}";
p=JsonHelper.JsonDeserialize<Person>(json);

        運行結果:

在后台替換字符串適用范圍比較窄,如果考慮到全球化的有多種語言還會更麻煩。

     2、利用JavaScript處理

簡單Demo :

ChangeDateFormat("//Date(1294499956278+0800)//");

     結果:

2011-1-8

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM