MVC Controller類下面有這樣一個方法
// // Summary: // Creates a System.Web.Mvc.JsonResult object that serializes the specified object // to JavaScript Object Notation (JSON). // // Parameters: // data: // The JavaScript object graph to serialize. // // Returns: // The JSON result object that serializes the specified object to JSON format. The // result object that is prepared by this method is written to the response by the // ASP.NET MVC framework when the object is executed. protected internal JsonResult Json(object data);
一般用在Action中返回一個JSON與客戶端JS(JQuery)互動。
public JsonResult getRepChangeTest() { return Json(myobj); }
當你的對像裡有日期時間欄位時,這個Json方法會把它序列化成這種格式
"rec_dt": "/Date(1498466813000)/",
在客戶端JS裡,我們把它當作字串處理一下,然後轉成js的日期格式,比如
function dt2(tm) { var time = tm.replace(/[\'\"\\\/\b\f\n\r\t)]/g, '').substring(5); console.log(time); //取得時間戳數值 var date = new Date(parseInt(time)); //轉成日期格式 //console.log(date); // 下面根據需要轉換成你要的格式 var month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; var currentDate = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); var hh = date.getHours() < 10 ? "0" + date.getHours() : date.getHours(); var mm = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes(); var dt= date.getFullYear() + "-" + month + "-" + currentDate + " " + hh + ":" + mm; alert(dt); }
可以還原成日期格式,如 2017-06-26 16:46,這一切看上去都很完美,然而,坑就在這裡。
Json方法返回的時間戳(毫秒數)是基於UTC時間的(GMT 0),而我的時區是GMT+8,所以這就有了8個小時的時差。
但是 js裡的var date = new Date(xxxxx); 這個是基於UTC時間的(測試所得,沒深究),所以客戶端得到的時間也是正確的。如果你用C#程式碼這樣手動驗證一下
DateTime.Parse("1970-1-1").AddSeconds(1498466813)
得到的日期剛好差8個小時。
MySQL中的日期型別有datetime, timestamp,如果使用datetime,如上沒有問題(雖然差個時區,但客戶端也是基於UTC還原的,所以能得到正確值),但當你使用timestamp時,Json方法序列化後的值是基於當前時區的,這樣js客戶端用上面的方法還原後就錯了,加了8個小時,因為客戶端是基於UTC的,對不上。 這是真正的坑所在。從資料庫裡讀出來,C#裡除錯兩個型別的值沒差別,都正確,但是把實體對像(定義的型別均為datetime)經Jons方法轉換後結果就不同,具體原來待研究……。
解決方法
1. 不使用Json轉換,用其它的,比如Newtonsoft.Json,經過JsonConvert.SerializeObject(obj)轉換後日期已經變成日期樣式的字串格式,直接顯示即可。
public ContentResult getRepChangeTest2() { var obj = rptdal.ReportChangeList(); string json=JsonConvert.SerializeObject(obj); return Content(json, "application/json"); }
2. 資料庫中不使用timestamp, 改用datetime型別