JsonConvert不转换UTC - > PopulateObject中的本地时间

时间:2014-04-02 13:13:25

标签: c# asp.net json timezone json.net

我的日期来自javascript到toJSON,所以它存储为UTC时间,但我想将它作为本地时间存储在数据库中(我们从未存储过UTC过去的时间,所以我需要继续这里的趋势。)

但是,在运行DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local时设置PopulateObject(使用版本6.0.0.0的Newtonsoft.Json)并没有做任何事情,它仍然保留为UTC日期原来的时间。

我的问题是:为什么它没有运行dt.ToLocalTime()来解决问题(并且是我当前的解决方法) - 或者:如果不是DateTimeZoneHandling.Local,我如何让转换器执行此操作?设置?

1 个答案:

答案 0 :(得分:5)

DateTime存储到数据库中作为本地时间通常不是一个好主意,因为:

  • 如果您的本地时区有daylight saving time条规则,那么您可能会丢失数据。在后退过渡期间,有一个小时的时间段,当地时间可能代表两个可能的时刻。使用UTC可以避免这个问题。

  • 它会将您的数据绑定到特定位置。如果您需要将服务器迁移到其他位置(或迁移到云端),则过去的数据将不准确。

如果必须以当地时间存储您的数据,请考虑将其存储为DateTimeOffset。通过记录偏移量,您可以准确地区分它所代表的唯一时间点,如果本地时区发生变化。这充分反驳了上述两点。

另请参阅:DateTime vs DateTimeOffset

关于你关于JSON.Net和DateTimeZoneHandling.Local选项的问题,这个简单的例子表明它似乎按设计工作。我无法重现你的主张。

public class Foo
{
    public DateTime DateTime { get; set; }
}

...

var json = "{\"DateTime\":\"2014-01-01T00:00:00.000Z\"}";

var settings = new JsonSerializerSettings
                    {
                        DateTimeZoneHandling = DateTimeZoneHandling.Local
                    };

var foo = JsonConvert.DeserializeObject<Foo>(json, settings);

Debug.WriteLine("{0} ({1})", foo.DateTime, foo.DateTime.Kind);

输出:

12/31/2013 16:00:00 (Local)

我当地的时区是美国太平洋时间,在提供的日期比UTC晚8小时,这反映在结果中。