Search code examples
c#datetimeoffsetjsonserializer

IsoDateTimeConverter and JsonSerializerSettings: differentiate DateTime with DateTimeOffset


In my C# models I use both DateTime and DateTimeOffset, eg:

   class Foo 
   {
        public DateTime Date { get; set; }
        public DateTimeOffset CreationDate { get; set; }
   } 

When I serialize to JSON, I do it like this:

  Foo foo = new Foo();
  foo.Date = DateTime.UtcNow;
  foo.CreationDate = DateTime.UtcNow;

  var isoDateTimeConverter = new IsoDateTimeConverter();
  isoDateTimeConverter.DateTimeFormat = "yyyy'-'MM'-'dd";

  var serializerSettings = new JsonSerializerSettings();
  serializerSettings.Converters.Add(isoDateTimeConverter);

  JsonSerializer serializer = JsonSerializer.Create(serializerSettings);
  serializer.Serialize(writer, foo);

This will produce this JSON:

 {
     Date = "2019-02-26",
     CreationDate = "2019-02-26"
 }

Both Date and CreationDate are serialized the same way due to IsoDateTimeConverter

What I'd like to do is to differentiate the serialization of DateTime and DateTimeOffset

My goal is to get this JSON:

 {
     Date = "2019-02-26",
     CreationDate = "2019-02-26T12:03:00-03:00"
 }

How can I achieve this?

Additional info:

  • When my C# model uses DateTime, I save it as Date in SQL Server
  • When my C# model uses DateTimeOffset, I save it as DateTimeOffset in SQL Server
  • I'm using EF Code First

Solution

  • You can try this

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

    Specify the format for each Date properties

    public class Foo
    {
        [JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd")]
        public DateTime Date { get; set; }
    
        [JsonConverter(typeof(DateFormatConverter), "yyyy-MM-ddTHH:mm:ssK")]
        public DateTimeOffset CreationDate { get; set; }
    }
    

    Without additional settings, you can Serialize

    Foo foo = new Foo();
    foo.Date = DateTime.UtcNow;
    foo.CreationDate = DateTime.UtcNow;
    
    string isoJson = JsonConvert.SerializeObject(foo);
    

    OUTPUT

    {"Date":"2020-02-26","CreationDate":"2020-02-26T15:30:19-03:00"}