【问题标题】:Parse a date json To DateTime将日期 json 解析为 DateTime
【发布时间】:2020-11-14 05:04:02
【问题描述】:

JSON 是:

{"date":13,"day":5,"hours":19,"minutes":6,"month":10,"nanos":0,"seconds":41,"time":1605265601000,"timezoneOffset":-480,"year":120}

当我尝试转换为DateTime时,遇到以下错误:

Newtonsoft.Json.JsonReaderException H结果=0x80131500 消息=解析值时遇到意外字符:{。路径'',第 1 行,位置 1。 来源=Newtonsoft.Json 堆栈跟踪: 在 Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType) 在 Newtonsoft.Json.JsonTextReader.ReadAsDateTime() 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) 在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader 阅读器,类型 objectType,布尔 checkAdditionalContent) 在 Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader 阅读器,类型 objectType) 在 Newtonsoft.Json.JsonConvert.DeserializeObject(字符串值,类型类型,JsonSerializerSettings 设置) 在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](字符串值,JsonSerializerSettings 设置) 在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](字符串值) 在 E:\code\UI\test\Program.cs:line 77 中的 test.Program.Main(String[] args) 处

我的代码:

var txt = "{\"date\":13,\"day\":5,\"hours\":19,\"minutes\":6,\"month\":10,\"nanos\":0,\"seconds\":41,\"time\":1605265601000,\"timezoneOffset\":-480,\"year\":120}";
var aa = Newtonsoft.Json.JsonConvert.DeserializeObject<DateTime>(txt);
Console.ReadKey();

当我改用 Newtonsoft.Json.dll 3.5 版本时,错误消失了。 当我改用Newtonsoft.Json.dll 9.0版本时,出现错误。

我正在使用 VS2017 构建,我的错误在哪里?

【问题讨论】:

  • 它正在搜索saleTime 不存在于DateTime 中的属性
  • 我认为您应该创建一个相应的 JSON txt 类并反序列化到您的类并使用方法公开 saleTime。
  • 我很抱歉这个错误,并再次编辑问题,销售时间被删除
  • 通过不删除saleTime 文本,我也尝试通过DateTime 属性创建一个类,例如public class DateTest { public DateTime saleTime { get; set; } },并将反序列化代码修改为此:`var aa = Newtonsoft. Json.JsonConvert.DeserializeObject(txt); `,错误也存在

标签: c# json


【解决方案1】:

我怀疑 Json.NET 现在期望 DateTime 值表示为字符串,而不是 JSON 对象。当然,你得到的代表是一个不寻常的代表。我建议你创建自己的遵循 JSON 的类,并写一个 ToDateTime(或者更好的 ToDateTimeOffset)来转换它。

(我很惊讶早期版本的 Json.NET 完全可以处理这个问题。)

更好的是,如果您可以控制创建此 JSON 的代码,最好将其更改为更合理的格式,例如一个 ISO-8601 字符串。

这是执行转换的代码示例。由于DateTimeOffset 的工作方式和偏移的表达方式混合在一起,偏移处理有点奇怪:(

using System;
using Newtonsoft.Json;

class Test
{
    static void Main()
    {
        var txt = "{\"date\":13,\"day\":5,\"hours\":19,\"minutes\":6,\"month\":10,\"nanos\":0,\"seconds\":41,\"time\":1605265601000,\"timezoneOffset\":-480,\"year\":120}";
        var jdto = JsonConvert.DeserializeObject<JsonDateTimeOffset>(txt);
        var dto = jdto.ToDateTimeOffset();
        Console.WriteLine(dto);
        Console.WriteLine(dto.ToUniversalTime());
    }
}

public class JsonDateTimeOffset
{
    // All ignored as the Time property handles all these.
    public int Date { get; set; }
    public int Day { get; set; }
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
    // Ignored, as we don't know what it means.
    public int Nanos { get; set; }
    
    // Milliseconds since the unix epoch
    public long Time { get; set; }
    
    // UTC offset in minutes, but reversed from the normal
    // view.
    [JsonProperty("timezoneOffset")]
    public int TimeZoneOffset { get; set; }
    
    public DateTimeOffset ToDateTimeOffset()
    {
        var instant = DateTimeOffset.FromUnixTimeMilliseconds(Time);
        var offset = -TimeSpan.FromMinutes(TimeZoneOffset);
        return new DateTimeOffset(instant.DateTime + offset, offset);
    }
}

【讨论】:

    【解决方案2】:

    你的反序列化对象实际上是

    public class Rootobject
    {
        public int date { get; set; }
        public int day { get; set; }
        public int hours { get; set; }
        public int minutes { get; set; }
        public int month { get; set; }
        public int nanos { get; set; }
        public int seconds { get; set; }
        public long time { get; set; }
        public int timezoneOffset { get; set; }
        public int year { get; set; }
    }
    

    并且您不能将此类直接反序列化为 DateTime。

    现在我想到了两个选项。 使用custom converter 或从RootObject 类的属性创建一个新的DateTime 实例。

    【讨论】:

    • “更具体地说,反斜杠似乎破坏了完整性。” - OP 的 JSON 不包含任何反斜杠。字符串文字可以,但 JSON 不会 - 尝试使用 OP 的第一行代码,然后编写 Console.WriteLine(txt);。您会看到没有反斜杠。
    • @JonSkeet 感谢您指出这一点!我再喝杯咖啡
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-21
    相关资源
    最近更新 更多