是否可以指定为的DateTimeOffset的JSON.NET反序列化偏移? [英] Is it possible to specify an offset for JSON.NET deserialization of DateTimeOffset?

查看:289
本文介绍了是否可以指定为的DateTimeOffset的JSON.NET反序列化偏移?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的语句打印1/1/0001下午4点00分〇〇秒-05:00

The following statement prints "1/1/0001 4:00:00 PM -05:00"

Console.WriteLine(JsonConvert.DeserializeObject<DateTimeOffset>("\"0001-01-01T16:00:00\""));

这是因为当json.net反序列化一个DateTime字符串(没有偏移量)来一个的DateTimeOffset对象,它赋予地方偏移,在这种情况下是-05:00

This is because when json.net deserializes a DateTime string (which doesn't have an offset) to a DateTimeOffset object, it assigns the local offset, which in this case is -05:00.

如果我不想使用本地偏移?有没有什么办法可以指定偏移量用于该反序列化?

What if I don't want to use the local offset? Is there any way I can specify an offset to use for this deserialization?

(用例是数据库服务器和Web服务器处于不同的时区,我需要有区域的不确定的时间让数据库服务器的传入的请求。反序列化抵销后)

(The use case is the database server and the web server are in different time zones, and I need the incoming requests that have zone-unspecified time to have the database server's offset after deserialization.)

更新:我无法控制传入时间字符串的格式。我有具有的DateTimeOffset属性的数据传输对象类,我需要进入的时间将数据存储到这个属性。

Update: I can't control the incoming time string's format. I have a data transfer object class which has a DateTimeOffset property and I need to store the incoming time data to this property.

推荐答案

您要反序列化到应与你所期望的数据类型。如果你不希望被列入偏移,那么就无法反序列化到一个的DateTimeOffset 。相反,反序列化到的DateTime 。这将有 DateTimeKind.Unspecified .Kind 属性。

The type you're deserializing into should match the data you are expecting. If you're not expecting an offset to be included, then don't deserialize into a DateTimeOffset. Instead, deserialize to a DateTime. It will have DateTimeKind.Unspecified for its .Kind property.

您对网络服务器的时区的知识是无关的反序列化的任务。所以单独应用它,后 - 事实。

The knowledge you have about the web server's time zone is extraneous to the task of deserialization. So apply it separately, after-the-fact.

// deserialize the json
DateTime dt = JsonConvert.DeserializeObject<DateTime>("\"2014-01-01T00:00:00\"");

// find your target time zone
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

// apply the time zone to determine the offset, and create the DateTimeOffset
DateTimeOffset dto = new DateTimeOffset(dt, tz.GetUtcOffset(dt));



更新

每个意见,如果你需要做你所要求的方式这种转换,你需要一个自定义的JSON转换器。这应该做的伎俩:

Per comments, if you need to do this conversion in the manner you've requested, you'll need a custom json converter. This should do the trick:

public class CustomDateTimeConverter : IsoDateTimeConverter
{
    private readonly string defaultTimeZoneId;

    public CustomDateTimeConverter(string defaultTimeZoneId)
    {
        this.defaultTimeZoneId = defaultTimeZoneId;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (objectType != typeof (DateTimeOffset) && objectType != typeof (DateTimeOffset?))
            return base.ReadJson(reader, objectType, existingValue, serializer);

        var dateText = reader.Value.ToString();
        if (objectType == typeof(DateTimeOffset?) && string.IsNullOrEmpty(dateText))
            return null;

        if (dateText.IndexOfAny(new[] { 'Z', 'z', '+'}) == -1 && dateText.Count(c => c == '-') == 2)
        {
            var dt = DateTime.Parse(dateText);
            var tz = TimeZoneInfo.FindSystemTimeZoneById(this.defaultTimeZoneId);
            var offset = tz.GetUtcOffset(dt);
            return new DateTimeOffset(dt, offset);
        }

        return DateTimeOffset.Parse(dateText);
    }
}



然后就可以在转换过程中连线起来:

Then you can wire it up during conversion:

var settings = new JsonSerializerSettings();
settings.DateParseHandling = DateParseHandling.None;
settings.Converters.Add(new CustomDateTimeConverter(defaultTimeZoneId: "Eastern Standard Time"));
DateTimeOffset dto = JsonConvert.DeserializeObject<DateTimeOffset>("\"2014-01-01T00:00:00\"", settings);



请务必使用一个有效的时区ID。不要使用固定的偏移量。

Be sure to used a valid time zone id. Do not use a fixed offset.

此外,这也不会,如果你想通过时间不注日期是正确的做法。这是一个完全不同的问题,并在 0001-01-01 传递的日期是不是一个伟大的方法。我会很乐意在聊天您讨论。

Also, this will not be the correct approach if you are trying to pass a time without a date. That is a completely different problem, and passing in 0001-01-01 for the date is not a great approach. I'll be happy to discuss with you in chat.

这篇关于是否可以指定为的DateTimeOffset的JSON.NET反序列化偏移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆