Here is how the export works
- .NET DataTable is created by a SQL Query
- DataSet is serialized and sent via HTTP Request to an Importer
- Importer Deserializes and performs a series of insert/updates; one per DataTable row
Details
- Exporting SQL Server is in the Eastern (US) Timezone
- Importing SQL Server is in the Central (US) Timezone
The Problem
- A datetime value is 1-3-2012 00:00:00 Eastern (midnight 1/3/12 Eastern)
- This value is exported through the previous mentioned mechanism
- When it is deposited to the destination (central) SQL Server, it has the value 1-2-2012 23:00:00 (11:00 PM the day before)
The datetime value should not change from one server to the next. It needs to stay 1-3-2012 00:00:00.
What have I tried?
- I have confirmed that the corresponding date values are indeed 1 hour off after re-running the export
- I have confirmed that an hour is not being subtracted by my code
- Serialization occurs via the BinaryFormatter.Serialize function, with the DataSet itself going right in
- Deserialization occurs via the BinaryFormatter.Deserialize function
- A call to a stored procedure is made with one parameter per column in the DataTable. I have confirmed that there is a direct copy for the date value via the following code:
CMD.Parameters("@p" & col.ColumnName).Value = row(col.ColumnName)
- I’ve analyzed the MSDN for DateTime, but based upon my understanding (storing Date in the first 4 bytes, time in the last 4 bytes) there should never be a switch to a different day, even if each block of 4 bytes represents some relative offset from some base day or time
- I have confirmed that the moment the DataSet is deserialized in the new timezone, all datetimes have shifted 1 hour
This really feels like a timezone issue, but I can’t figure out where it might be.
Transferring a datetime from one SQL Server to another SQL Server via an
UPDATEquery across a Linked Server connection will preserve the date and time. 1/3/12 Midnight comes across as 1/3/12 Midnight, despite the time zone change.However, by injecting the dates into a .NET Dataset, you subject the SQL DateTime variables to a data conversion to .NET DateTime.
The display of a DateTime varies by TimeZone. If you load the same bits in Boston as you do in California via the ToString() function, you will get two different results.
As a result, by the time this code is called, the damage is done
CMD.Parameters("@p" & col.ColumnName).Value = row(col.ColumnName)To fix this problem, you must either determine the time zone offset and adjust the value, or serialize to a safer format, thus avoiding the .NET DateTime, as mentioned by @competent_tech.
References