Передача дат в наборах данных по уровням - PullRequest
2 голосов
/ 09 ноября 2010

У меня есть набор данных, который я передаю в веб-сервис в стиле asmx. если я вызываю метод «GetXml» на ds, содержимое отображается в виде следующей строки:

<ChinaVisa>
  <ChinaVisa>
    <ChinaVisaId>5</ChinaVisaId>
    <ReceiveDate>2010-11-07T23:00:14-05:00</ReceiveDate>
  </ChinaVisa>
</ChinaVisa>

Затем я передаю этот XML как параметр NTEXT хранимой процедуре. Хранимая процедура (упрощенная) имеет следующий код:

DECLARE @ChinaVisaHandle INT

ALTER PROCEDURE [dbo].[UpdateOrder]
(
   @xmlChinaVisa NTEXT
)
AS

      EXEC sp_xml_PrepareDocument
         @ChinaVisaHandle OUTPUT,
         @xmlChinaVisa
      SELECT
         ChinaVisaId,
         ReceiveDate
      INTO   #TempChinaVisa
      FROM
         OPENXML (@ChinaVisaHandle, '/ChinaVisa/ChinaVisa', 2)
            WITH ( [ChinaVisaId]     INT,
                   ReceiveDate       DATETIME
                   )

Затем я использую данные в таблице #TempChinaVisa, чтобы записать их в фактическую основную таблицу.

  UPDATE [ChinaVisa]
  SET    
         ReceiveDate       = #TempChinaVisa.ReceiveDate
  FROM   #TempChinaVisa
  WHERE  #TempChinaVisa.ChinaVisaId = [ChinaVisa].ChinaVisaId

Когда я запрашиваю таблицу ChinaVisa, мне отображается ReceiveDate, скорректированное на 5-часовое смещение, по существу, устанавливающее временную метку в GMT. (Я понимаю, что набор данных содержал это смещение -5 по Гринвичу.)

Результат запроса таблицы назначения базы данных:

SELECT ReceiveDate       FROM ChinaVisa

    OrderId ReceiveDate     
    5   2010-11-08 04:00:00 

Это меня немного удивило. Поскольку все уровни приложений были локальными, я сначала не ожидал преобразования в другой часовой пояс. Дата, введенная в GUI, при преобразовании в набор данных включала смещение местного часового пояса на 5 часов. Когда я использовал Mgt Studio для отображения даты, я предполагаю, что Mgt Studio должен был решить, будут ли отображаться даты по местному времени или по Гринвичу. Я ожидал, что все будет преобразовано в локальное, но, поскольку он отображал его, как показано выше, он выглядит так, как те Mgt Studio отображал метку времени по времени GMT.

Хотя немного удивительно, это не вызывало тревоги. Тем не менее, когда мое приложение WinForm использовало веб-сервис для запроса данных, я ожидал, что при обращении к нему через набор данных дата будет автоматически настроена на местное время, аналогично тому, как она автоматически конвертируется при сохранении в базу данных, но не было. Когда я переместил ReceiveDate в элемент управления DateTimePicker, отображалась дата «2010-11-08 04:00:00».

Если бы я выполнил еще одно сохранение, чтобы взять дату из элемента управления DatePicker и сохранить ее в базе данных, это привело бы к неожиданной корректировке даты. В результате значение в базе данных будет меняться на 5 часов при каждом обновлении экрана из базы данных и его повторном сохранении без изменения значения на экране.

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

Несколько советов?

1 Ответ

0 голосов
/ 09 ноября 2010

В общем, самый разумный способ обработки дат в распределенной системе - хранить все в формате UTC и при необходимости преобразовывать только в местное время для представления пользователю.На мой беглый взгляд, твоя ситуация, кажется, ничем не отличается.Если у вас есть такая возможность, я бы настоятельно рекомендовал собирать / хранить / получать только даты и времени UTC.Попытка смешать смещения часовых поясов вручную - это вызов безумия и отчаяния.

...