Why can DateTime.MinValue not be serialized in timezones ahead of UTC?

c#, datetime, json, serialization, wcf

Solution

The main problem is `DateTime.MinValue` has `DateTimeKind.Unspecified` kind. It is defined as:

MinValue = new DateTime(0L, DateTimeKind.Unspecified);

But this is not a real problem, this definition leads to problem during serialization. JSON DateTime serialization done through:

System.Runtime.Serialization.Json.JsonWriterDelegator.WriteDateTime(DateTime value)

Unfortunately it is defined as:

...

if (value.Kind != DateTimeKind.Utc)
{
    long num = value.Ticks - TimeZone.CurrentTimeZone.GetUtcOffset(value).Ticks;
    if ((num > DateTime.MaxValue.Ticks) || (num < DateTime.MinValue.Ticks))
    {
        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(XmlObjectSerializer.CreateSerializationException(SR.GetString("JsonDateTimeOutOfRange"), new ArgumentOutOfRangeException("value")));
    }
}

...

So it doesn't take into account `Unspecified` and treats it as `Local`. To avoid this situation you can define your own constant:

MinValueUtc = new DateTime(0L, DateTimeKind.Utc);

or

MinValueUtc = DateTime.MinValue.ToUniversalTime();

It looks weird of course, but it helps.

Problem

I am experiencing issues with a WCF REST service. The wire object that I try to return has certain properties not set, resulting in DateTime.MinValue for properties of type DateTime. The service returns an empty document (with HTTP status 200 ???). When I try to call JSON serialization myself, the exception that is thrown is: SerializationException: DateTime values that are greater than DateTime.MaxValue or smaller than DateTime.MinValue when converted to UTC cannot be serialized to JSON. This can be reproduced by running the following code in a console app: ``` DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DateTime)); MemoryStream m = new MemoryStream(); DateTime dt = DateTime.MinValue; // throws SerializationException in my timezone ser.WriteObject(m, dt); string json = Encoding.ASCII.GetString(m.GetBuffer()); Console.WriteLine(json); ``` Why is this behaviour? I think it is related to my timezone (GMT+1). As DateTime.MinValue is default(DateTime), I would expect that this can be serialized without problems. Any tips on how to make my REST service behave? I don't want to change my DataContract.

Original source

Related problems