跨层传递数据集中的日期

时间:2010-11-09 01:58:34

标签: .net sql-server xml ado.net dataset

我有一个数据集,我将其传递给asmx样式的Web服务。如果我在ds上调用“GetXml”方法,则内容显示为以下字符串:

<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 GMT偏移值。)

查询数据库目标表的结果:

SELECT ReceiveDate       FROM ChinaVisa

    OrderId ReceiveDate     
    5   2010-11-08 04:00:00 
这让我有些惊讶。由于所有应用程序层都是本地的,我起初并没有指望任何转换到另一个时区。在GUI中输入的日期,当转换为数据集时,包括5小时的本地时区偏移量。当我使用Mgt Studio显示日期时,我想Mgt Studio必须决定显示的日期是当地时间还是GMT。我原本希望将所有内容转换为本地,但由于它如上图所示显示,因此显示为那些Mgt Studio在GMT时间内显示时间戳。

虽然有点令人惊讶,但并不令人担忧。但是,当我的WinForm应用程序使用Web服务查询数据时,我预计通过数据集访问的日期将自动调整为本地时间,类似于保存到数据库时自动转换的方式,但是它不是。当我将ReceiveDate移动到DateTimePicker控件时,显示的日期是“2010-11-08 04:00:00”。

如果我执行另一次保存以从DatePicker控件获取日期并将其保存到数据库,这将导致对日期的意外调整。因此,每次从数据库刷新屏幕并重新保存时,数据库中的值将更改5小时,而无需更改屏幕上的值。

处理这种情况的最恰当/最简单的方法是什么?我的直觉反应是在显示之前将从数据库读取的所有日期时间转换为本地时间,但我不确定如果数据库服务器或Web服务层在不同时区运行,这种情况是否会变得更复杂。

一些建议?

1 个答案:

答案 0 :(得分:0)

通常,处理分布式系统中日期的最安全方法是以UTC格式存储所有内容,并且只根据需要转换为本地时间以进行用户演示。在我粗略的眼中,你的情况似乎没有什么不同。如果您有能力,我强烈建议收集/存储/检索 UTC日期时间。尝试手动混合时区偏移是为了引起疯狂和绝望。