Dot-Net

JSON 日期序列化和時區

  • March 5, 2013

我在使用 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而不是 a DateTime

// 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 控制項將遵守偏移量並適當地應用它。如果不是,那麼剩下的問題是特定於您正在使用的控制項。

引用自:https://stackoverflow.com/questions/14427631