JSON 日期序列化和時區
我在使用 JSON 序列化對像在客戶端瀏覽器上顯示正確日期時遇到問題。使用者能夠定義他們想要查看數據的時區。鑑於此,我將 UTC 日期轉換為伺服器上使用者的時區。然後我想通過 JSON 將日期/時間(已經轉換為其定義的時區)序列化到瀏覽器。
看起來很簡單,但是我一直在使用的 JSON 序列化程序嚴重破壞了我的日期。伺服器使用 UTC,客戶端使用 Central (-6)。即使我將 DateTime.Kind 指定為未指定,日期也會被調整(-12 小時)。
不知何故,.NET 知道客戶端瀏覽器所在的時區以及伺服器所在的時區,即使我已經根據使用者的全域設置調整了時間並設置了日期,它也會從我的日期/時間中否定 -6種類不詳。如何讓 JSON 序列化程序不嘗試調整我的日期?
List<ErrorGridModel> models = Mapper.Map<ErrorCollection, List<ErrorGridModel>>(errors); foreach (ErrorGridModel m in models) { //convert UTC dates to user local dateTime - split out date vs. time for grouping & splitting columns DateTime dtLocal = TimeZoneInfo.ConvertTimeFromUtc(m.ErrorDate, this.AppContext.User.TimeZoneInfo); m.ErrorDate = new DateTime(dtLocal.Year, dtLocal.Month, dtLocal.Day, 0, 0, 0, DateTimeKind.Unspecified); m.ErrorTime = new DateTime(1900, 1, 1, dtLocal.Hour, dtLocal.Minute, dtLocal.Second, DateTimeKind.Unspecified); } IQueryable<ErrorGridModel> dataSource = models.AsQueryable(); return new ContentResult() { Content = JsonConvert.SerializeObject(dataSource.ToDataSourceResult(request), new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat }), ContentType = "application/json" }; //return Json(dataSource.ToDataSourceResult(request));ISO 日期似乎有效,但我無法使用它們,因為我有需要舊版 Microsoft 格式的 3rd 方控制項……它會調整我的時區。
這是關於我所處的確切情況的長時間討論。 http://www.telerik.com/community/forums/aspnet-mvc/grid/grids-and-dates.aspx
最重要的是,如果您使用 Microsoft JSON 日期格式,它將始終以 UTC 格式反映日期,即從 1970 年 1 月 1 日 UTC 開始的毫秒數(滴答聲)。我無法在伺服器上將時間自動轉換為本地時間,並通過 JSON 將它應該下降的時間發送到 Kendo Grid,因為 Kendo Grid 控制項將 JS 中的刻度中的日期實例化為 UTC。顯示此日期時,它會自動將該值轉換為瀏覽器的本地時區。
從伺服器顯示我的伺服器轉換後的日期值的唯一方法是通過 JSON 將日期作為字元串發送到客戶端。
當你試圖控制偏移量時,不要依賴
DateTimeKind.Unspecified. 它有一些通常被解釋為Unspecified == Local. 讓 Json.Net 專門編碼正確的偏移量(無論 ISO 或 MS 格式)的唯一方法是傳遞它 aDateTimeOffset而不是 aDateTime。// Start with the UTC time, for example your m.ErrorDate. // Here I demonstrate with UtcNow. Any DateTime with .Kind = UTC is ok. var dt = DateTime.UtcNow; // Use the appropriate time zone, here I demonstrate with EST. var tzi = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"); // Get the offset from UTC for the time zone and date in question. var offset = tzi.GetUtcOffset(dt); // Get a DateTimeOffset for the date, and adjust it to the offset found above. var dto = new DateTimeOffset(dt).ToOffset(offset); // Serialize to json var json = JsonConvert.SerializeObject(dto, new JsonSerializerSettings { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat, }); // The json should now contain the correct time and offset information. // For example, "\/Date(1358789156229-0500)\/"現在希望您會發現您正在使用的 javascript 控制項將遵守偏移量並適當地應用它。如果不是,那麼剩下的問題是特定於您正在使用的控制項。