【问题标题】:Getting NodaTime.Serialization.JsonNet to work with a custom date format让 NodaTime.Serialization.JsonNet 使用自定义日期格式
【发布时间】:2017-11-15 15:22:40
【问题描述】:

我正在尝试反序列化一个 JSON,其中包含 2017-10-26 13:32:11 Etc/GMT 格式的日期。 NodaTimeJson.NETNodaTime.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.) 引发异常。我做错了什么?

【问题讨论】:

  • 你必须使用DateTimeOffset而不是野田时间OffsetDateTime类型吗?一般来说,如果你能完全坚持 Noda Time 类型,生活会更简单。
  • 不,我可以使用任何类型,但没有太大区别,我只是得到另一个错误; 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.)。尝试了几种不同的模式变体,没有 ' 等,并尝试了几种不同的类型,OffsetDateTimeZonedDateTime,但错误仍然相同。
  • 如果您愿意将值设为ZonedDateTime,您应该可以让它工作。 (当我建议OffsetDateTime 时,我没有发现实际上您的值包含时区,而不是偏移量。)目前,问题不在于这种方法 - 删除您当前的答案和将问题更改为“让 NodaTime.Serialization.JsonNet 使用自定义格式”或为此创建一个新问题。不管怎样,我绝对想提供帮助......
  • 问题已更新:)
  • 太好了,谢谢。现在将开始工作。

标签: c# json json.net deserialization nodatime


【解决方案1】:

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

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

创建一个转换器并为此配置设置很简单:

var settings = new JsonSerializerSettings
{
    DateParseHandling = DateParseHandling.None,
    Converters = { new NodaPatternConverter<ZonedDateTime>(pattern) }
};

这是在完整程序的上下文中的样子。请注意,我在这里明确使用 DateTimeZoneProviders.Tzdb,而不是 DateTimeZoneProviders.Serialization,因为您肯定有 TZDB 标识符:

using Newtonsoft.Json;
using NodaTime;
using NodaTime.Serialization.JsonNet;
using NodaTime.Text;
using System;

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

class Program
{
    static 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.Tzdb
        );

        var settings = new JsonSerializerSettings
        {
            DateParseHandling = DateParseHandling.None,
            Converters = { new NodaPatternConverter<ZonedDateTime>(pattern) }
        };
        var dateObj = JsonConvert.DeserializeObject<DateObj>(json, settings);
        Console.WriteLine(dateObj.Date);
    }
}

【讨论】:

  • public static JsonSerializerSettings ConfiguredForNodaTime(这个 JsonSerializerSettings 设置,IDateTimeZoneProvider 提供者) { LocalDatePattern pattern = LocalDatePattern.CreateWithInvariantCulture("dd-MMM-yyyy"); AddToDefaultConverters(settings.Converters, provider,pattern); settings.DateParseHandling = DateParseHandling.None;返回设置; }
  • @stephenebichondo:我不太确定您的评论的重点。你能澄清一下吗?
猜你喜欢
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-10
  • 1970-01-01
  • 2020-11-17
  • 2021-01-06
相关资源
最近更新 更多