我在使用JSON序列化对象的客户端浏览器上显示正确的日期时遇到问题。用户能够定义他们想要查看数据的时区。鉴于此,我将UTC日期转换为服务器上用户的时区。然后我想通过JSON序列化日期/时间(已经转换为其定义的时区)到浏览器。
看起来很简单,但是我一直在使用的JSON序列化器已经严重弄乱了我的日期。服务器使用UTC,客户端使用Central(-6)。即使我指定了DateTime,日期也在被调整(-12小时)。Kind to Unspecified
不知何故。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日期似乎可以工作,但我不能使用它们,因为我有第三方控件想要旧的微软格式…它可以帮我调整时区
当你试图控制偏移量时,不要依赖DateTimeKind.Unspecified
。它有一些怪癖,通常被解释为Unspecified == Local
。获取Json的唯一方法。Net专门编码正确的偏移量(无论ISO或MS格式)是传递一个DateTimeOffset
而不是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控件将尊重偏移量并适当地应用它。如果不是,那么问题的其余部分是特定于您正在使用的控件。
这里有一个关于我所处的确切情况的长讨论。http://www.telerik.com/community/forums/aspnet-mvc/grid/grids-and-dates.aspx
底线,如果您使用Microsoft JSON日期格式,它将始终将UTC中的日期反映为从1970年1月1日UTC开始的毫秒数(刻度)。我没有办法在服务器上自动将时间转换为本地时间,并将应该通过JSON发送到剑道网格,因为剑道网格控件将JS中的刻度实例化为UTC的日期。当显示此日期时,它会自动将该值转换为浏览器的本地时区。
显示服务器从服务器转换的日期值的唯一方法是将日期通过JSON作为字符串发送到客户端。
我们也遇到了这个问题。正如您所注意到的,问题实际上发生在客户端。通过在网格中使用请求结束处理程序,您可以将日期转换回UTC。示例如下:
http://www.kendoui.com/code-library/mvc/grid/using-utc-time-on-both-client-and-server-sides.aspx