The Problem with Dates, Timezones and XmlConvert

A recent post by Brad Abrams on DateTime, Serialization and TimeZones highlights one of the problems with the the System.Datetime structure. The best way to illustrate his problem is with a code fragment and the output from the code

DateTime now = DateTime.Now; 
DateTime now2 = now.ToUniversalTime(); 
    
Console.WriteLine(now);
Console.WriteLine(now2);

Console.WriteLine(XmlConvert.ToString(now));
Console.WriteLine(XmlConvert.ToString(now2));

which results in the following output

4/14/2004 9:29:31 AM
4/14/2004 4:29:31 PM
2004-04-14T09:29:31.9531250-07:00
2004-04-14T16:29:31.9531250-07:00

which at first seems right until you consider that all the values should reflect the same instant in time but do not. The problem is that the DateTime structure does not store time zone information which causes all sorts of problems when trying to transmit date or time values across the network or persist them. I've had to deal with this because I'm responsible for the System.Xml.XmlConvert class and have been working with folks that are responsible for XML Serialization, the DataSet and the CLR team as to how best to work around this problem. As Brad Abrams mentions in his blog post 

You can mark a DateTime instance as Local, UTC or Unspecified, and Unspecified means that it should not be serialized with a time zone. Unfortunately it won't magically take effect because it would break compatibility. But there will be ways to opt-in to this behavior for DataSet, XML Serialization and XML Convert.

 so there won't be time zone information added to the type but at the very least it should be possible to get my code fragment above to emit equivalent times in Whidbey. So time zone information still won't be supported but you can always normalize to UTC and have this preserved correctly instead of what happens now.

This is what has been proposed and I'm in the process of working out exactly how this should work for XmlConvert. We will most likely add overloads to the ToString method that takes a DateTime that allows people to control whether they want the backwards compatible (but incorrect) v1.0 behavior or the correct behavior when outputing a UTC date.