2009-11-10 6 views
5

Tengo una aplicación que lee los datos de SQL y enviarlo a través de WCF para una aplicación cliente, de una manera similar a esto:Cómo DataSet.Fill con valores de fecha y hora predeterminados a DateTimeKind.Utc?

SqlDataAdapter da = new SqlDataAdapter(cmd) 
DataSet ds = new DataSet(); 
da.Fill(ds); 
return ds; 

Toda la fecha/horas se almacenan en la base de datos como UTC. Lo que noté es que si el reloj en la computadora que ejecuta la aplicación está sesgado, la fecha/horas recibidas por los clientes también serán sesgadas. Parece que en el caso de que el tipo DateTime no sea del tipo especificado, WCF lo representará como hora local internamente y lo enviará como tal, por lo que cualquier diferencia de tiempo entre la aplicación y el cliente hará que la fecha/hora cambie.

Sin duda podría ir a través de los conjuntos de datos que se recuperan y fijar campos de fecha/hora, pero ¿alguien aquí pensar en una mejor manera de llenar el conjunto de datos, para que cada campo DateTime sería DateTimeKind.Utc en da.Fill automáticamente()?

Respuesta

15

Si está utilizando SQL Server 2008, la solución "adecuada" es usar el tipo de datos SQL datetimeoffset en lugar de la fecha y hora de SQL. datetimeoffset es un tipo de fecha/hora compatible con la zona horaria nuevo en SQL 2008, y se traducirá en ADO.NET en el tipo CLR System.DateTimeOffset que siempre es relativo a UTC. Aquí hay un blog post entrando en más detalles sobre esto. El first few search results on MSDN for DateTimeOffset proporciona información de fondo adicional.

Si no puede cambiar su esquema de SQL, ADO.NET tiene una propiedad a medida para esta situación: DataColumn.DateTimeMode, que controla si se añade zona horaria local cuando el conjunto de datos es de serie (DateTimeMode=DataSetDateTime.UnspecifiedLocal, que es el valor por defecto) o si no se agrega información de zona horaria en la serialización (DateTimeMode=DataSetDateTime.Unspecified). Quieres esto último

Si mi lectura de los documentos de MSDN es correcta, debe poder establecer DateTimeMode=DataSetDateTime.Unspecified para el DataColumn en cuestión después de llenar el DataSet. Esto debería serializar la columna sin una zona horaria.

Si quieres ser realmente adecuada (o en caso de que el enfoque anterior no funciona), se puede crear el DataTable antes de tiempo y establecer que la columna de DateTimeMode=DataSetDateTime.Utc antes Fill -ing con filas. Entonces está seguro de enviar la fecha como UTC.

+0

"Set DateTimeMode = DataSetDateTime.Unspecified para la DataColumn en cuestión después de que se llene el DataSet" funcionó a la perfección. ¡Gracias! – galets

+0

genial, me alegro de ayudar. –

+0

Para eliminar el desplazamiento enviado en valores DateTime con formato JSON, establezca 'DateTimeMode = DataSetDateTime.Utc'. – Suncat2000

Cuestiones relacionadas