让NodaTime.Serialization.JsonNet使用自定义日期格式

时间:2017-11-15 15:22:40

标签: c# json json.net deserialization nodatime

我正在尝试反序列化JSON,其中包含2017-10-26 13:32:11 Etc/GMT格式的日期。与NodaTimeJson.NET结合使用时,NodaTime.Serialization.JsonNet似乎支持此功能。我在StackOverflow上找到了一些信息,这些信息让我只使用了NodaTime:

var date = "2017-10-26 13:32:11 Etc/GMT";

var pattern = ZonedDateTimePattern.CreateWithInvariantCulture(
    "yyyy'-'MM'-'dd HH':'mm':'ss z", 
    DateTimeZoneProviders.Tzdb
);

var result = pattern.Parse(date);

然而,当将此示例扩展为使用其他两个包反序列化JSON时,我无法使其工作。从阅读文档和其他资源,我相信这应该工作:

public class DateObj
{
    public ZonedDateTime Date { get; set; }
}

void Main()
{
    var date = "2017-10-26 13:32:11 Etc/GMT";
    var json = $"{{\"Date\": \"{date}\"}}";

    var pattern = ZonedDateTimePattern.CreateWithInvariantCulture(
        "yyyy-MM-dd HH:mm:ss z",
        DateTimeZoneProviders.Serialization
    );

    var settings = new JsonSerializerSettings();
    settings.ConfigureForNodaTime(pattern.ZoneProvider);
    var dateObj = JsonConvert.DeserializeObject<DateObj>(json, settings);
}

但它在最后一行说The value string does not match a quoted string in the pattern. Value being parsed: '2017-10-26^ 13:32:11 Etc/GMT'. (^ indicates error position.)时引发了异常。我做错了什么?

1 个答案:

答案 0 :(得分:3)

目前,您正在创建一个特定的ZonedDateTime模式 - 但您实际上并没有在任何地方告诉Json.NET该模式。

如果这是您需要使用的 only Noda Time类型,我建议您根本不要调用ConfigureForNodaTime - 因为这将配置{{1转换器使用错误的模式。我们有code internal to NodaTime.Serialization.JsonNet来替换转换器,但目前尚未公开。 (也许我们应该这样做......)

虽然创建单个转换器很简单,并为其配置设置:

ZonedDateTime

这是完整程序环境中的样子。请注意,我明确地使用var settings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.None, Converters = { new NodaPatternConverter<ZonedDateTime>(pattern) } }; ,而不是DateTimeZoneProviders.Tzdb,因为您确实拥有TZDB标识符:

DateTimeZoneProviders.Serialization