.net - JSON 日期序列化和时区

标签 .net json datetime timezone json.net

我在使用 JSON 序列化对象在客户端浏览器上显示正确日期时遇到问题。用户能够定义他们想要查看数据的时区。鉴于此,我将 UTC 日期转换为服务器上用户的时区。然后我想通过 JSON 将日期/时间(已转换为其定义的时区)序列化到浏览器。

看起来很简单,但是我一直在使用的 JSON 序列化器严重搞乱了我的日期。服务器采用 UTC,客户端采用中部 (-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 日期似乎有效,但我无法使用它们,因为我有第 3 方控件,需要旧的 Microsoft 格式...它会调整我的时区。

最佳答案

当您尝试控制偏移量时,不要依赖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 控件将遵循偏移量并适本地应用它。如果不是,那么剩下的问题就与您所使用的控件有关。

关于.net - JSON 日期序列化和时区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14427631/

相关文章:

c# - 如何在 C# 中比较没有时间部分的日期时间

c# - 多线程工作线程状态

.net - Entity Framework 4.0 在插入前自动截断/修剪字符串

c# - 一个Windows服务中的多个服务进程(System.ServiceProcess.ServiceBase)

javascript - Jquery 自动完成以多个数组作为源

json - MarkLogic 8 - 即使我们指定了 JSON,Rest 端点也返回 XML

c# - 如何匹配文件内容中的正则表达式模式而不循环遍历文件中的每一行?

Python 3 通过索引从 json 获取值

java - 具有不确定性的 JUnit 日期时间比较

java - 如何在Java 8中查找下个月的第一个星期日?