0

When serializing DateTime or DateTimeOffset, I'm getting inconsistent results depending on second fraction. If fraction == 0, second part is 00, yet if fraction > 0, second part is 00.999.

class MyDateHoldingThingy
{
    public DateTime DateTime { get; set; }
    public DateTimeOffset DateTimeWithTz { get; set; }
    public string GimmeJson()
    {
        return JsonConvert.SerializeObject(this);
    }
}

public void SerializeDateThingy(int fraction)
{
    var d = new MyDateHoldingThingy
    {
        DateTime = new DateTime(2017, 4, 3, 19, 21, 0, fraction),
        DateTimeWithTz = new DateTimeOffset(2017, 4, 3, 19, 21, 0, fraction, TimeSpan.FromHours(2))
    };

    Console.WriteLine(d.GimmeJson());
}

Calling with

SerializeDateThingy(0);
SerializeDateThingy(999);

Result

{"DateTime":"2017-04-03T19:21:00","DateTimeWithTz":"2017-04-03T19:21:00+02:00"}
{"DateTime":"2017-04-03T19:21:00.999","DateTimeWithTz":"2017-04-03T19:21:00.999+02:00"}

If using Newtonsoft JSON directly, I can pass

new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fff" }

... which gives me desired consistency. I'm trying to fix output in our solution, which is mixture of WCF/ASP.NET+OData and I don't even know whether serialization happens via Json.net and not via .NET serializer (but that would most probably produced Date(...) value) - still need to investigate more, however I didn't see any direct reference to Json.net.

Please note that I'm not doing serialization myself! This is covered by OData when dealing with output. I have actually no power to call serializer directly in my case. Code above is just example showing output inconsistency, which is seemingly default behavior.

So far, questions are:

  • How do I set custom IsoDateTimeConverter globally (if Json.net is used)?
  • How do I set custom format to .NET (JSON and XML) serializers?
  • Could anyone point me to RFC where it says that if second fraction equals to 0, it's completely omitted?
Zdeněk
  • 929
  • 1
  • 8
  • 25
  • 1
    What do you mean you don't want to rely on Json.Net if someone takes it off? Like removes the reference? Why would someone ever remove a reference that's being used? But anyway... if that format works, then you can just use `dateTime.ToString("yyyy-MM-ddTHH:mm:ss.fff")` to return the result regardless of framework. – Dispersia Apr 03 '17 at 17:39
  • Yes, if someone decides "oh, don't want to use this any more" (I know, it's silly reason). I have rephrased my question - I'm actually not handling serialization myself, it is provided by OData, which itself decides what serializer to use (XML, JSON) depending on Accept headers. So neither calling `ToString("...")` or instantiating `IsoDateTimeConverter` is not working for me here. – Zdeněk Apr 03 '17 at 17:51
  • Format information (with all links you need) https://en.wikipedia.org/wiki/ISO_8601 (and the picture https://xkcd.com/1179/ :) ) – Alexei Levenkov Apr 03 '17 at 17:53
  • @AlexeiLevenkov That was first thing I read, but don't see anything related to omitting fraction if 0. Could you please quote or rephrase, perhaps missed that. Thanks! – Zdeněk Apr 03 '17 at 18:12
  • https://tools.ietf.org/html/rfc3339#appendix-A: "time = timespec-base [time-fraction] [time-zone]", you may also find http://stackoverflow.com/questions/522251/whats-the-difference-between-iso-8601-and-rfc-3339-date-formats useful as it highlights difference between ISO8601 nad RFC3339. – Alexei Levenkov Apr 03 '17 at 18:31
  • As written, your question is far too broad, and is at least partially off-topic as well. It's also not clear what you actually want. The difference in the output is simply one of efficiency. Why emit trailing decimal point and zeroes if they add nothing to the information stored? Why is it important to you that when the fraction is 0, you still get `00.000` as the output? How is that useful? – Peter Duniho Apr 03 '17 at 18:46
  • @PeterDuniho: This is not important to me, but for consumer of our API, who has some sort of problem with parsing inconsistent values. Either I prove them it behaves according to standard (I wasn't able to find it; kudos to @AlexeiLevenkov) or I will configure our serializers (JSON, XML) globally so it keeps these irrelevant zeroes at the end. – Zdeněk Apr 03 '17 at 19:03
  • _"Could anyone point me to RFC..."_ -- requests for off-site resources are explicitly off-topic. As for the rest, it's up to you. But if I were you, I would not waste time customizing standard serialization behavior just to accommodate consumers who can't be bothered to deserialize valid data correctly. – Peter Duniho Apr 03 '17 at 19:04

0 Answers0