简体   繁体   English

在每个类中使用不同的格式序列化同一类中的多个DateTime属性

[英]Serializing multiple DateTime properties in the same class using different formats for each one

I have a class with two DateTime properties. 我有一个带有两个DateTime属性的类。 I need to serialize each of the properties with a different format. 我需要使用不同的格式序列化每个属性。 How can I do it? 我该怎么做? I tried: 我试过了:

JsonConvert.SerializeObject(obj, Formatting.None,
      new IsoDateTimeConverter {DateTimeFormat = "MM.dd.yyyy"});

This solution doesn't work for me because it applies date format to all the properties. 该解决方案对我不起作用,因为它将日期格式应用于所有属性。 Is there any way to serialize each DateTime property with different format? 有什么方法可以序列化具有不同格式的每个DateTime属性? Maybe there is some attribute? 也许有一些属性?

A straightforward way to handle this situation is to subclass the IsoDateTimeConverter to create a custom date converter for each different date format that you need. 处理这种情况的一种直接方法是将IsoDateTimeConverter子类化, IsoDateTimeConverter所需的每种不同日期格式创建一个自定义日期转换器。 For example: 例如:

class MonthDayYearDateConverter : IsoDateTimeConverter
{
    public MonthDayYearDateConverter()
    {
        DateTimeFormat = "MM.dd.yyyy";
    }
}

class LongDateConverter : IsoDateTimeConverter
{
    public LongDateConverter()
    {
        DateTimeFormat = "MMMM dd, yyyy";
    }
}

Then you can use the [JsonConverter] attribute to decorate the individual DateTime properties in any classes which need custom formatting: 然后,您可以使用[JsonConverter]属性来装饰需要自定义格式的任何类中的各个DateTime属性:

class Foo
{
    [JsonConverter(typeof(MonthDayYearDateConverter))]
    public DateTime Date1 { get; set; }

    [JsonConverter(typeof(LongDateConverter))]
    public DateTime Date2 { get; set; }

    // Use default formatting
    public DateTime Date3 { get; set; }
}

Demo: 演示:

Foo foo = new Foo
{
    Date1 = DateTime.Now,
    Date2 = DateTime.Now,
    Date3 = DateTime.Now
};

string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
Console.WriteLine(json);

Output: 输出:

{
  "Date1": "03.03.2014",
  "Date2": "March 03, 2014",
  "Date3": "2014-03-03T10:25:49.8885852-06:00"
}

NewtonSoft.Json has a structure that's a bit difficult to understand, you can use something like the following custom converter to do what you want: NewtonSoft.Json的结构有点难以理解,您可以使用以下自定义转换器之类的东西来做您想要的事情:

[TestMethod]
public void Conversion()
{
    var obj = new DualDate()
    {
        DateOne = new DateTime(2013, 07, 25),
        DateTwo = new DateTime(2013, 07, 25)
    };
    Assert.AreEqual("{\"DateOne\":\"07.25.2013\",\"DateTwo\":\"2013-07-25T00:00:00\"}", 
        JsonConvert.SerializeObject(obj, Formatting.None, new DualDateJsonConverter()));
}

class DualDate
{
    public DateTime DateOne { get; set; }
    public DateTime DateTwo { get; set; }
}

class DualDateJsonConverter : JsonConverter
{

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {

        JObject result = new JObject();

        DualDate dd = (DualDate)value;

        result.Add("DateOne", JToken.FromObject(dd.DateOne.ToString("MM.dd.yyyy")));
        result.Add("DateTwo", JToken.FromObject(dd.DateTwo));
        result.WriteTo(writer);
    }

    // Other JsonConverterMethods
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(DualDate);
    }

    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

You can create a custom date class that inherits the IsoDateTimeConverter and pass a format on the constructor. 您可以创建一个自定义的日期类,该类继承IsoDateTimeConverter并在构造函数上传递格式。 On the attributes, you can specify which format corresponds to each property. 在属性上,可以指定每种属性对应的格式。 See code below: 参见下面的代码:

public class LoginResponse
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }
    [JsonProperty("token_type")]
    public string TokenType { get; set; }
    [JsonProperty("expires_in")]
    public DateTime ExpiresIn { get; set; }
    [JsonProperty("userName")]
    public string Username { get; set; }
    [JsonConverter(typeof(CustomDateFormat), "EEE, dd MMM yyyy HH:mm:ss zzz")]
    [JsonProperty(".issued")]
    public DateTime Issued { get; set; }
    [JsonConverter(typeof(CustomDateFormat), "MMMM dd, yyyy")]
    [JsonProperty(".expires")]
    public DateTime Expires { get; set; }
}

public class CustomDateFormat : IsoDateTimeConverter
{
    public CustomDateFormat(string format)
    {
        DateTimeFormat = format;
    }
}

I realise this is an old question, but I stumbled upon it during my search for same question. 我意识到这是一个古老的问题,但是在寻找相同问题时偶然发现了它。

Newtonsoft has now a DateFormatString property in JsonSerializerSettings class which you can use. Newtonsoft现在可以在JsonSerializerSettings类中具有DateFormatString属性。 I came to this question looking for answer and have just found the property, I have used it as below and it works as below: 我来到这个问题中寻找答案,并且刚刚找到了该物业,我按如下所示使用了它,其工作原理如下:

    private const string _StrDateFormat = "yyyy-MM-dd HH:mm:ss";

    private static string GetJSON(object value)
    {

        return JsonConvert.SerializeObject(value, new JsonSerializerSettings
        {
            DateFormatString = _StrDateFormat
        });
    }

When value will have a DateTime object, it will convert it into string respecting _StrDateFormat string. value具有DateTime对象时,它将_StrDateFormat字符串将其转换为字符串。

Perhaps this official link can be updated? 也许此官方链接可以更新?

Regards. 问候。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM