Thursday, January 19, 2006

Serializing data across time zones in .NET 2.0

This week I've been implementing support in our framework for the new DateTimeMode setting on the DataColumn class. This property is used on DateTime columns to determine a couple things; 1) it specifies how dates should be stored in the column and 2) how a date should be serialized when marshalling across time zones. Setting the DateTimeMode to Local or Utc will not only affect serialization but will also affect how the data is stored in the column. Setting to Unspecified or UnspecifiedLocal does not affect the storage, just the serialization. In .NET 1.x the dataset would always serialize dates as UnspecifiedLocal. This means it would apply the appropriate local time offset when it deserialized. So if you entered the value 12/1/2005 00:00:00 in Florida and passed that dataset to California it would show up as 11/30/2005 21:00:00. This can be a problem depending on the meaning of the datetime value. If you are say storing this in a database and/or not using the time part, when you display the date part to the user you have a problem.

One way to solve this in 1.x is to use a surrogate class which also provides the added ability to serialize the data as true binary. When wrapping the dates up in the surrogate before serialization, you can have it not apply the offset to the DateTime columns. However this approach works across the entire set of columns in the dataset; there's no granularity.

So here comes the DateTimeMode in .NET 2.0. You can set each individual column to the mode you want and the serialization will behave exactly how you want. Great. So lets start designing our typed datasets and you'll notice a DateTimeMode property in the property sheet in the designer. Set that to the mode you want and regenerate your typed datasets... right? WRONG. There's a bug in the designer (and XSD.EXE) where it refuses to code spit the DateTimeMode even though it's properly declared in the xsd file. Well that totally sucks. For more info see the bug report.

So the work around is that you have to set the DateTimeMode at runtime before serializing. Also be careful if your merging an untyped dataset into a typed dataset because the DateTimeMode on the typed dataset will prevail in that case. (See the documentation on compatible merges.)

So with all the workaround code I now have running I turn my attention to the new binary serialization support in the 2.0 DataSet. My initial performance numbers are NOT impressive at all. In fact, the Xml serialization is much faster for small sets of data. This is in drastic contrast to the surrogate class I was using in 1.x. The surrogate class performs better in all cases. I'm updating the surrogate to include the new DateTimeMode support and once I have it all tested I'll post a new GotDotNet sample. I'll also post some more formal numbers once I finish my tests.

3 comments:

Kjetil Klaussen said...

"Thanks for the info on the bug regarding serializing datetime columns with the DateTimeMode set, but it sure caught me with my guard down that the DataSet designer was fudging it up! I developed an application a couple of months a go and set the DateTimeMode to DataSetDateTime.Unspecified. But I never actually verified the serialized dataset after writing it to disk, because it all worked as expected at that time. Unfortunately; now that the clock is about to be adjusted for daylight savings (the application is run in GMT +1), the application starts throwing constraint exceptions when deserializing the dataset! The DateTime column is part of a PrimaryKey on the table (only one value allowed for a specific moment of time) and so when the serializer adjusts for daylight savings, I suddenly get 2 values for the same moment of time; 2006-03-26T03:00:00!

Anyway; it was good that the .Net team has taken into account this framework deficiency from v 1.x, but it was a real bummer to find out that nobody informed the DataSet designer about these changes… Unfortunately this is just one in a series of bugs and frustrating flaws in VS 2005. Do you know if there are any plans for releasing any VS 2005 service pack sometime soon? "

Beth Massi said...

Looks like they fixed it and it'll be in the next release.

James said...

Thanks for the info, I found it helpful. Hopefully Microsoft hurries up with the next release ;)