首页 > 解决方案 > JsonSerializer:区分 DateTime 对象的种类

问题描述

我有一个包含日期(以及其他数据)的动态对象。

其中一些日期有 Kind UTC,其他日期有 Kind Local,例如:

var dynamicObject = new 
{
     utcDate = DateTime.UtcNow,    //This one has Kind = DateTimeKind.Utc
     localDate = DateTime.Now      //This one has Kind = DateTimeKind.Local
}

然后我有一个 JsonSerializer,它的工作原理如下:

var isoDateTimeConverter = new IsoDateTimeConverter();
isoDateTimeConverter.DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'";
                                            //                       ^
                                            //                  Notice this

var serializerSettings = new JsonSerializerSettings();
SerializerSettings.Converters.Add(isoDateTimeConverter);

var response = context.HttpContext.Response;
var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };

var serializer = JsonSerializer.Create(serializerSettings);
serializer.Serialize(writer, dynamicObject);

writer.Flush();

它创建了一个 JSON 字符串,如下所示:

{
     "utcDate":"2019-05-02T19:52:20Z",
     "localDate":"2019-05-02T15:52:20Z"
}

这是预期的,因为 myisoDateTimeConverter当前是如何定义的。

但我想序列化如下:

{
     "utcDate":"2019-05-02T19:52:20Z",
     "localDate":"2019-05-02T15:52:20"    // <--- no Z
}

这意味着我只想在 DateTime 的种类为 Utc 时添加“Z” 。

IsoDateTimeConverter和/或这可能JsonSerializerSettings吗?

标签: c#jsonserializer

解决方案


我会在IsoDateTimeConverter不设置的情况下使用DateTimeFormat,它输出完整的DateTime值,以秒为单位,如果是,则为“Z”,如果DateTimeKind是,则为UTC“+-HH:mm”格式的时区偏移量Local(如果是空字符串None)。

否则,说明K将根据您的需要格式化该值,并为与 UTC 的偏移量附加相同的值。

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

public class Program
{
    public static void Main(string[] args)
    {
        var dynamicObject = new
        {
            utcDate = DateTime.UtcNow, //This one has Kind = DateTimeKind.Utc
            localDate = DateTime.Now //This one has Kind = DateTimeKind.Local
        }

        ;
        var isoDateTimeConverter = new IsoDateTimeConverter();
        isoDateTimeConverter.DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK";
        var serializerSettings = new JsonSerializerSettings();
        serializerSettings.Converters.Add(isoDateTimeConverter);
        var s = new System.Text.StringBuilder();
        using (var w = new System.IO.StringWriter(s))
        using (var writer = new JsonTextWriter(w)
                   {Formatting = Formatting.Indented})
        {
            var serializer = JsonSerializer.Create(serializerSettings);
            serializer.Serialize(writer, dynamicObject);
            writer.Flush();
        }

        Console.WriteLine(s.ToString());
    }
}

点网小提琴

ISO 8601 格式允许任意精度的日期和时间的多种变化。来自维基百科关于 ISO 8601 的文章

小数部分的小数位数没有限制。但是,小数位数需要通信双方同意。


推荐阅读