【问题标题】:Ignoring timezone offset when deserializing datetime反序列化日期时间时忽略时区偏移
【发布时间】:2017-05-24 19:01:09
【问题描述】:

我的 json 中有一个日期时间,格式如下:

“事件日期”:“2017-05-05T11:35:44-07:00”,

这个文件是在太平洋时间创建的,而我的服务器是在东部时间。当我将此文件反序列化回我的对象​​时,时间将转换为 2017-05-05 2:35:44PM 的日期时间。问题是我需要原始时间,上午 11:35:44。

我已经从源头上解决了这个问题,但我仍然需要一种方法来处理我拥有的所有这些文件。有没有办法将此字段反序列化为指定的确切日期时间而没有偏移量?我检查了 DateTimeZoneHandling 设置,但都没有产生我想要的效果。

【问题讨论】:

  • 您可以在序列化/反序列化时使用DateTimeOffset 对象类型,这将维护时区信息,允许您在需要的任何时区显示它。否则,我建议将其传输为 GMT (.ToUniversalTime()) 请记住,2017-05-05 14:35:44 -04:00 与 2017-05-05 11:35:44 - 07:00 相同
  • @MarkEmbling 是的,现在我同意你的看法。我试图在类的属性设置器中修改 DateTime,但发现要设置的值已经转换为本地时间。
  • 我将日期时间存储为 GMT,并将其转换为尽可能接近客户端的本地时间(例如 JS,而不是 json 响应)

标签: c# json datetime json.net


【解决方案1】:

我同意上述 cmets 中的 AWinkle - 最好的方法是将反序列化为 DateTimeOffset 而不是 DateTime - 这样,您可以根据需要显示它。

也就是说,我将这个想法用于一种可能的方法,即使用自定义 JSON 类型转换器来获得您想要的时区剥离行为。这是我敲出的一个快速示例,它似乎按照您的要求进行。

/// <summary>
/// Custom converter for returning a DateTime which has been stripped of any time zone information
/// </summary>
public class TimezonelessDateTimeConverter : DateTimeConverterBase {
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
        throw new NotImplementedException("An exercise for the reader...");
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
        // We'll make use of Json.NET's own IsoDateTimeConverter so 
        // we don't have to re-implement everything ourselves.
        var isoConverter = new IsoDateTimeConverter();

        // Deserialise into a DateTimeOffset which will hold the 
        // time and the timezone from the JSON.
        var withTz = (DateTimeOffset)isoConverter.ReadJson(reader, typeof(DateTimeOffset), existingValue, serializer);

        // Return the DateTime component. This will be the original 
        // datetime WITHOUT timezone information.
        return withTz.DateTime;
    }
}

然后可以这样使用:

/// <summary>
/// Nonsense class just to represent your data. You'd implement the JsonConverter
/// attribute on your own model class.
/// </summary>
public class Sample {
    [JsonConverter(typeof(TimezonelessDateTimeConverter))]
    public DateTime EventDate { get; set; }
}

//
// And a sample of the actual deserialisation...
///

var json = "{ \"EventDate\": \"2017-05-05T11:35:44-07:00\" }";
var settings = new JsonSerializerSettings {
    DateParseHandling = DateParseHandling.DateTimeOffset
};
var deserialised = JsonConvert.DeserializeObject<Sample>(json, settings);
Console.WriteLine(deserialised.EventDate);

这将输出05/05/2017 11:35:44

这绝对不是最可靠的方法,我几乎可以肯定有些事情我没有考虑到 - 并且可能应该进行更彻底的测试以确保没有一些可怕的副作用。但希望这是一个可能的解决方案的起点,并为您指明正确的方向。

附:如果您还序列化回 JSON,则还需要实现 WriteJson 方法。我没有做那个,所以现在它只朝一个方向发展。

【讨论】:

    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2014-04-13
    相关资源
    最近更新 更多