【问题标题】:Serializing multiple DateTime properties in the same class using different formats for each one序列化同一类中的多个 DateTime 属性,每个属性使用不同的格式
【发布时间】:2013-07-25 06:16:06
【问题描述】:

我有一个具有两个 DateTime 属性的类。我需要用不同的格式序列化每个属性。我该怎么做?我试过了:

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

此解决方案对我不起作用,因为它将日期格式应用于所有属性。有没有办法用不同的格式序列化每个 DateTime 属性?也许有一些属性?

【问题讨论】:

    标签: c# .net json serialization json.net


    【解决方案1】:

    处理这种情况的一种直接方法是将IsoDateTimeConverter 子类化,以便为您需要的每种不同日期格式创建自定义日期转换器。例如:

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

    然后您可以使用[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; }
    }
    

    演示:

    Foo foo = new Foo
    {
        Date1 = DateTime.Now,
        Date2 = DateTime.Now,
        Date3 = DateTime.Now
    };
    
    string json = JsonConvert.SerializeObject(foo, Formatting.Indented);
    Console.WriteLine(json);
    

    输出:

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

    【讨论】:

      【解决方案2】:

      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();
          }
      }
      

      【讨论】:

        【解决方案3】:

        您可以创建一个继承 IsoDateTimeConverter 的自定义日期类,并在构造函数上传递格式。在属性上,您可以指定每个属性对应的格式。见以下代码:

        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;
            }
        }
        

        【讨论】:

          【解决方案4】:

          我意识到这是一个老问题,但我在搜索同一个问题时偶然发现了它。

          Newtonsoft 现在在 JsonSerializerSettings 类中有一个 DateFormatString 属性,您可以使用它。我来到这个问题寻找答案并刚刚找到了该属性,我已按如下方式使用它,它的工作原理如下:

              private const string _StrDateFormat = "yyyy-MM-dd HH:mm:ss";
          
              private static string GetJSON(object value)
              {
          
                  return JsonConvert.SerializeObject(value, new JsonSerializerSettings
                  {
                      DateFormatString = _StrDateFormat
                  });
              }
          

          value 有一个DateTime 对象时,它会将其转换为符合_StrDateFormat 字符串的字符串。

          也许this official link可以更新?

          问候。

          【讨论】:

          • 虽然确实可以使用此设置在每次序列化时全局更改日期格式,但它并不能解决问题中的问题:如何序列化包含两个日期的对象并使用每个日期不同的格式。
          猜你喜欢
          • 2017-04-01
          • 1970-01-01
          • 2014-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多