Как DataSet.Fill со значениями DateTime по умолчанию DateTimeKind.Utc? - PullRequest
6 голосов
/ 11 ноября 2009

У меня есть приложение, которое считывает данные из SQL и отправляет их через WCF в клиентское приложение, подобно следующему:

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

Все дата / время хранятся в базе данных как UTC. Что я заметил, так это то, что если часы на компьютере, на котором запущено приложение, искажены, дата / время, полученные клиентами, также будут искажены. Кажется, что в случае, когда тип DateTime имеет неопределенный тип, WCF будет представлять его как локальное время внутри страны и отправлять как таковой, поэтому любая разница во времени между приложением и клиентом приведет к смещению даты / времени.

Я, конечно, мог бы просматривать наборы данных по мере их извлечения и фиксировать поля даты / времени, но кто-нибудь здесь придумал бы какой-нибудь лучший способ заполнить набор данных, чтобы каждое поле DateTime автоматически было DateTimeKind.Utc на da.Fill )

Ответы [ 2 ]

16 голосов
/ 11 ноября 2009

Если вы используете SQL Server 2008, то «правильным» решением будет использование типа данных SQL datetimeoffset вместо даты-времени SQL. datetimeoffset является типом даты / времени с учетом часового пояса, новым для SQL 2008, и будет переведен в ADO.NET в тип CLR System.DateTimeOffset, который всегда относится к UTC. Вот пост в блоге , в котором более подробно об этом говорится. * Первые несколько результатов поиска в MSDN для DateTimeOffset предоставляют дополнительную справочную информацию.

Если вы не можете изменить свою схему SQL, ADO.NET имеет свойство, специально созданное для этой ситуации: DataColumn.DateTimeMode, которое определяет, будет ли добавлен местный часовой пояс при сериализации набора данных (DateTimeMode=DataSetDateTime.UnspecifiedLocal (по умолчанию) или информация о часовом поясе не добавляется при сериализации (DateTimeMode=DataSetDateTime.Unspecified). Вы хотите последнее.

Если мое чтение документов MSDN правильное, вы сможете установить DateTimeMode=DataSetDateTime.Unspecified для рассматриваемого DataColumn после заполнения DataSet. Это должно сериализовать столбец без часового пояса.

Если вы хотите быть по-настоящему правильным (или в случае, если описанный выше подход не работает), вы можете заранее создать DataTable и установить для этого столбца значение DateTimeMode=DataSetDateTime.Utc перед Fill, то есть строки. Тогда вы уверены, что отправили дату как UTC.

0 голосов
/ 22 февраля 2019

В моем случае измените значение свойства DateTimeMode связанных столбцов на «Unspecialed» вместо значения по умолчанию «UnspecialedLocal» в схеме XSD.

...