How to solve: DataSets change DateTime values when transmitted across time zones
In my last post, I described how I discovered that DataSet objects when transmitted across time zones would alter the DateTime objects to match the new time zone. As I mentioned then, this was a problem as we weren't transmitting the time zone information with the DataSets, so we couldn't translate the times back. The data we were collecting was more time-of-day specific than universal time specific. We were interested in data around times like “rush hour” which we could define on the side where we received the data. But we couldn't very well define rush hour when 6pm on the west coast was reading as 9pm when we received it on the east coast.
We briefly toyed with the idea of modifying the XML of all serialized DataSets after they were received but before they were deserialized. Rather than what is probably a questionable engineering decision and doing this to all DatSets without regard to their purpose, we settled on a solution based on what we learned about the DateTimeMode property of all DataColumns with a DataType of DateTime at https://connect.microsoft.com/wcf/feedback/details/488856/datetime-values-in
I wrote an extension method for the DataSet type. Now you can set the DateTimeMode property of all columns in a DataSet all at once.
Now to preserve the local time values within a DataSet, I call myDataSet.SetDateTimeMode(DataSetDateTime.Unspecified)
before I transmit the DataSet across the network. Hope this helps!
Imports System.Runtime.CompilerServices
Public Module DataSetExtensions
''' <summary>Sets the
''' <see cref="System.Data.DataColumn.DateTimeMode">DateTimeMode</see>
''' property for all <see cref="System.Data.DataColumn">System.Data.DataColumn</see>
''' objects within the <see cref="System.Data.DataSet">System.Data.DataSet</see>
''' where the data type is <see cref="System.DateTime">DateTime</see>.</summary>
''' <param name="d">The <see cref="System.Data.DataSet">System.Data.DataSet</see>
''' to modify.</param>
''' <param name="dateTimeMode">The new date time mode to apply to every
''' <see cref="System.Data.DataColumn">System.Data.DataColumn</see> where the
''' data type is <see cref="System.DateTime">System.DateTime</see>.</param>
<Extension()> _
Public Sub SetDateTimeMode(ByVal d As DataSet, dateTimeMode As DataSetDateTime)
For Each t As DataTable In d.Tables
For Each c As DataColumn In t.Columns
If c.DataType Is GetType(DateTime) Then
c.DateTimeMode = dateTimeMode
End If
Next
Next
End Sub
End Module