2009-11-10 13 views
5

Ho un'applicazione che leggere i dati da SQL e inviarlo via WCF per un'applicazione client, in modo simile a questo:Come DataSet.Fill con valori DateTime predefiniti a DateTimeKind.Utc?

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

tutte le informazioni/tempi sono memorizzati nel database come UTC. Quello che ho notato è che se l'orologio sul computer che esegue l'applicazione è distorto, anche la data/l'ora ricevuta dai client sarà distorta. Sembra che nel caso in cui il tipo DateTime sia di tipo non specificato, WCF lo rappresenterà come ora locale internamente e invierà come tale, quindi qualsiasi differenza di orario tra l'applicazione e il client causerà lo spostamento di data/ora.

Potrei sicuramente passare attraverso i set di dati mentre vengono recuperati e correggere i campi data/ora, ma qualcuno qui potrebbe pensare ad un modo migliore per riempire il set di dati, in modo che ogni campo DateTime sia automaticamente DateTimeKind.Utc su da.Fill()?

risposta

15

Se si utilizza SQL Server 2008, la soluzione "corretta" consiste nell'utilizzare il tipo di dati SQL datetimeoffset anziché il datetime di SQL. datetimeoffset è un tipo di data/ora sensibile al fuso orario nuovo a SQL 2008 e verrà convertito in ADO.NET nel tipo CLR System.DateTimeOffset che è sempre relativo a UTC. Ecco uno blog post andando in maggiori dettagli su questo. Il first few search results on MSDN for DateTimeOffset fornisce ulteriori informazioni di base.

Se non è possibile modificare lo schema di SQL, ADO.NET ha una proprietà su misura per questa situazione: DataColumn.DateTimeMode, che controlla se si aggiunge fuso orario locale quando il set di dati viene serializzato (DateTimeMode=DataSetDateTime.UnspecifiedLocal, che è l'impostazione predefinita) o se non è stata aggiunta alcuna informazione sul fuso orario sulla serializzazione (DateTimeMode=DataSetDateTime.Unspecified). Tu vuoi il secondo.

Se la lettura dei documenti MSDN è corretta, è necessario impostare DateTimeMode=DataSetDateTime.Unspecified per DataColumn in questione dopo che il DataSet è stato compilato. Questo dovrebbe serializzare la colonna senza un fuso orario.

Se vuoi essere veramente corretta (o nel caso in cui l'approccio di cui sopra non funziona), è possibile creare il DataTable in anticipo e impostare quella colonna di DateTimeMode=DataSetDateTime.Utc prima Fill -ing con righe. Quindi hai la certezza di inviare la data come UTC.

+0

"Imposta DateTimeMode = DataSetDateTime.Unspecified per DataColumn in questione dopo il riempimento del DataSet" ha funzionato perfettamente. Grazie! – galets

+0

cool, felice di aiutare. –

+0

Per rimuovere l'offset inviato in valori DateTime formattati JSON, impostare 'DateTimeMode = DataSetDateTime.Utc'. – Suncat2000

Problemi correlati