Thursday, May 29, 2008

Experiment in the Fidelity of UTC DateTime

// make sure your local clock is not displaying GMT

DateTime a = new DateTime(2008, 7, 6, 4, 3, 2, DateTimeKind.Utc);
DateTime b = new DateTime(2008, 7, 6, 4, 3, 2, DateTimeKind.Local);
DateTime c = new DateTime(2008, 7, 6, 4, 3, 2, DateTimeKind.Unspecified);

// no surprises here...
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);

// and again, no surprises. this makes it that much more explicit.
Console.WriteLine("-");
Console.WriteLine(a.ToUniversalTime());
Console.WriteLine(b.ToUniversalTime());
Console.WriteLine(c.ToUniversalTime());

// notice the Z(ulu) for UTC, the time zone for local, and the (nothing) for unspecified
Console.WriteLine("-");
XmlSerialize(a);
XmlSerialize(b);
XmlSerialize(c);

// ooh! our first loss of fidelity
Console.WriteLine("-");
DataSet dataSet = new DataSet();
DataTable dataTable = dataSet.Tables.Add();
DataColumn dataColumn = dataTable.Columns.Add("DateTime", typeof(DateTime));
dataTable.Rows.Add(a);
dataTable.Rows.Add(b);
dataTable.Rows.Add(c);
Console.WriteLine(dataSet.GetXml());

// those .net framework guys fight back with the DateTimeMode property (new in 2.0)
// understandably, weird stuff starts happening when not all input dates are of the same kind
Console.WriteLine("-");
DataSet dataSet2 = new DataSet();
DataTable dataTable2 = dataSet2.Tables.Add();
DataColumn dataColumn2 = dataTable2.Columns.Add("DateTime", typeof(DateTime));
dataColumn2.DateTimeMode = DataSetDateTime.Utc;
dataTable2.Rows.Add(a);
dataTable2.Rows.Add(b);
dataTable2.Rows.Add(c);
Console.WriteLine(dataSet2.GetXml());

//you can't just get the bytes for a DateTime, it's a struct.
//Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(a)));
//Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(b)));
//Console.WriteLine(BitConverter.ToString(BitConverter.GetBytes(c)));

Console.ReadKey();

2 comments:

Jono said...

private static void XmlSerialize(DateTime value)
{
XmlSerializer serializer = new XmlSerializer(typeof(DateTime));
using (StringWriter writer = new StringWriter())
{
serializer.Serialize(writer, value);
Console.WriteLine(writer.GetStringBuilder());
}
}

Jono said...

Taken from sybase.com: "The datetime and smalldatetime datatypes, however, do not store time zone information and the products are entirely ignorant of the concepts of time zones and daylight saving time."