使用Json.Net以dd/mm/yyyy格式反序列化日期

gir*_*tri 36 c# json json.net

我正在尝试将对象从JSON数据反序列化为C#类(我使用的是Newtonsoft Json.NET):数据包含字符串值中的日期,如09/12/2013格式所在dd/MM/yyyy.

如果我调用JsonConvert.DeserializeObject<MyObject>(data) 日期加载到C#类的日期时间属性DateTime,然后日期值是2013年9月12日(而不是2013年12月9日).

是否可以配置JsonConvert以正确的格式获取日期?

Bri*_*ers 45

您可以使用IsoDateTimeConverter并指定DateTimeFormat以获得所需的结果,例如:

MyObject obj = JsonConvert.DeserializeObject<MyObject>(jsonString, 
                   new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" });
Run Code Online (Sandbox Code Playgroud)

演示:

class Program
{
    static void Main(string[] args)
    {
        string json = @"{ ""Date"" : ""09/12/2013"" }";

        MyObject obj = JsonConvert.DeserializeObject<MyObject>(json, 
            new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" });

        DateTime date = obj.Date;
        Console.WriteLine("day = " + date.Day);
        Console.WriteLine("month = " + date.Month);
        Console.WriteLine("year = " + date.Year);
    }
}

class MyObject
{
    public DateTime Date { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

输出:

day = 9
month = 12
year = 2013
Run Code Online (Sandbox Code Playgroud)


小智 7

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

var dateTimeConverter = new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" };
myObject obj = JsonConvert.DeserializeObject<myObject>(myJSONString, dateTimeConverter);
Run Code Online (Sandbox Code Playgroud)


Ufu*_*arı 6

您也可以在JsonSerializer中配置它:

var serializer = new JsonSerializer
{
    DateFormatString = "dd/MM/yyyy"
};
Run Code Online (Sandbox Code Playgroud)


dea*_*anN 6

多格式支持:

这就是我用的:

public class CustomDateTimeConverter : IsoDateTimeConverter
{
    public CustomDateTimeConverter()
    {
        base.DateTimeFormat = "dd/MM/yyyy";
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您将执行以下操作:

public class MyObject
{
    [JsonConverter(typeof(CustomDateTimeConverter))]
    public DateTime Date {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

然后使用您之前做过的任何普通方式反序列化...

MyObject obj = JsonConvert.DeserializeObject<MyObject>(json);
Run Code Online (Sandbox Code Playgroud)

另类

其他方式与@pimbrouwers所说的相同:

public class MyObject
{
    [JsonProperty("Date")] //Naturally Case Sensetive
    private string dateJson {get;set;}
    // it would be good to look at @pimbrouwers answer and use nullable
    [JsonIgnore]
    public DateTime Date
    {
        get
        {
            return DateTime.ParseExact(dateJson,"dd/MM/yyyy",CultureInfo.InvariantCulture);
        }
        set
        {
            dateJson = value.ToString("dd/MM/yyyy");
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

自定义DateTimeConverter

我也只写了这个,自定义DateTime转换器,它将与您的自定义超出范围格式或日历相匹配

public class CustomDateTimeConverterJalali : DateTimeConverterBase
{
    //I had no use for WriteJson section, i just wrote it, so i do not guarantee it working
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        var nullableType = Nullable.GetUnderlyingType(value.GetType());
        var isNullable = nullableType != null;

        DateTime date;
        if (isNullable)
            date = ((DateTime?) value).Value;
        else
            date = (DateTime) value;


        PersianCalendar pc = new PersianCalendar();

        writer.WriteValue(pc.GetYear(date) + "/" + pc.GetMonth(date) + "/" + pc.GetDayOfMonth(date));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        //this should likely be null, but since the provider json returned empty string, it was unavoidable... (i'm not sure what we will read using reader, if data is actually null on the json side, feel free to experiment 
        if (string.IsNullOrWhiteSpace((string) reader.Value))
        {
            return null;
        }

        var strDate = reader.Value.ToString();

        PersianCalendar pc = new PersianCalendar();
        var dateParts = strDate.Split('/');

        DateTime date = pc.ToDateTime(int.Parse(dateParts[0]), int.Parse(dateParts[1]), int.Parse(dateParts[2]),
            0, 0, 0, 0);

        return date;
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DateTime);//DateTime=>true | DateTime?=>true
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:

您提供的其他方式是一次配置的,并且可能更简单并且在大多数时候有用。...但是在这里,提供者为我提供了一项服务,该服务在每个对象中提供两种格式的日期,并且这些对象之一在不同的日历中分别提供两个日期...所以很高兴知道我在这里提供的这两种方式