Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 您能告诉JSON.Net将日期时间序列化为Utc(即使未指定)?_Javascript_Asp.net_Entity Framework_Json.net - Fatal编程技术网

Javascript 您能告诉JSON.Net将日期时间序列化为Utc(即使未指定)?

Javascript 您能告诉JSON.Net将日期时间序列化为Utc(即使未指定)?,javascript,asp.net,entity-framework,json.net,Javascript,Asp.net,Entity Framework,Json.net,我的数据库中的日期存储为Utc。但当我用实体框架检索它们时,它们显示为未指定类型 当JSON.Net序列化它们时,它们不是Utc格式。有没有一种方法可以告诉JSON.Net将日期时间序列化为Utc,即使其类型未指定为Utc?将JsonSerializerSettings上的DateTimeZoneHandling设置为Utc。这将在序列化日期之前将所有日期转换为UTC public void SerializeObjectDateTimeZoneHandling() { string jso

我的数据库中的日期存储为Utc。但当我用实体框架检索它们时,它们显示为未指定类型


当JSON.Net序列化它们时,它们不是Utc格式。有没有一种方法可以告诉JSON.Net将日期时间序列化为Utc,即使其类型未指定为Utc?

JsonSerializerSettings上的
DateTimeZoneHandling
设置为
Utc
。这将在序列化日期之前将所有日期转换为UTC

public void SerializeObjectDateTimeZoneHandling()
{
  string json = JsonConvert.SerializeObject(
    new DateTime(2000, 1, 1, 1, 1, 1, DateTimeKind.Unspecified),
    new JsonSerializerSettings
    {
      DateTimeZoneHandling = DateTimeZoneHandling.Utc
    });

  Assert.AreEqual(@"""2000-01-01T01:01:01Z""", json);
}

文档:

上面的响应完全有效,因此我使用它创建了一个属性,将API响应从PST转换为UTC

首先,我需要创建一个
JsonConverter

public class UTCDateTimeConverter : Newtonsoft.Json.JsonConverter {
    private TimeZoneInfo pacificZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
    public override bool CanConvert(Type objectType) {
        return objectType == typeof(DateTime);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        if (reader.Value == null) return null;
        var pacificTime = DateTime.Parse(reader.Value.ToString());
        return TimeZoneInfo.ConvertTimeToUtc(pacificTime, pacificZone);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        writer.WriteValue(TimeZoneInfo.ConvertTimeFromUtc((DateTime) value, pacificZone));
    }
}
然后我必须将其应用于需要转换的属性

public class Order{
    [JsonConverter(typeof(UTCDateTimeConverter))]
    public DateTime OrderDate {get;set;}
}

正如@dez在评论中提到的,从DB加载DateTime对象之后,在序列化它们之前,您可以直接在.net代码中将它们“标记”为UTC:

var item = GetItemFromDb(...);

// mark appropriate DateTime fields manually as needed
item.OrderDate = DateTime.SpecifyKind(item.OrderDate, DateTimeKind.Utc);

// now it will be serialized to "2018-10-17T16:21:23.507Z" with the Z at the end
// and javascript will parse it properly and convert to local timezone as needed

对我来说,为日期时间属性创建UTC转换器更简单(基于Newtonsoft.Json.Converters.IsoDateTimeConverter的实现)


我使用了接受的答案,但适用于默认设置:

        JsonConvert.DefaultSettings = (() =>
        {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(new StringEnumConverter());
            settings.Formatting = Formatting.Indented;
            settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            return settings;
        });

我建议您在数据层中执行DateTime.SpecifyKind(),以便它返回正确的日期。大于或改用DateTimeOffset。数据库中出现的未指定类型是一个常见问题,当系统的时区不是UTC时,它可能会导致许多其他问题。我同意你的看法。我只是不知道一个干净的方法来指定使用EF代码的第一种。你是英雄。看起来你对Json.net很熟悉!对我来说,是否有一种方法可以处理属性或全局(在网站中,而不是api中),这实际上没有什么区别。My DateTimes的种类==“未指定”,但它们实际上是本地的。无论我是否有这个DateTimeZoneHandling,它都做同样的事情——假设UTC。我想这是有道理的,但当我看到这个答案时,我想它会将我的本地时间转换为UTC。请注意,myDateTime.ToUniversalTime()将其从本地转换为UTC。这应该是默认值。使用推断的本地时区偏移量反序列化为时区较少的DateTime是非常棘手的行为。是的,但默认情况下假设时区较少的DateTime为UTC是疯狂的。最好使用;return DateTime.Parse(date|text,CultureInfo.InvariantCulture,DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal)
        JsonConvert.DefaultSettings = (() =>
        {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(new StringEnumConverter());
            settings.Formatting = Formatting.Indented;
            settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            return settings;
        });