大约四年前,我遵循了这个 MSDN 文章 有关在 .Net 1.1 和 ASMX Web 服务(以 SQL 2000 服务器作为后端)上构建 .Net 客户端的 DateTime 使用最佳实践。我仍然记得 DateTime 遇到的序列化问题以及对不同时区的服务器进行的测试工作。

我的问题是这样的:对于 WCF 和 SQL Server 2008 等一些新技术,是否有类似的最佳实践文档,特别是添加了用于存储时区感知信息的新日期时间类型。

这是环境:

  1. SQL Server 2008(太平洋时间)。
  2. Web 服务层位于不同的时区。
  3. 客户端可以在不同时区使用.Net 2.0 或.Net 3.5。如果方便的话,我们可以强制每个人升级到 .Net 3.5。:)

对于每层使用的数据类型有什么好的建议/最佳实践吗?

有帮助吗?

解决方案

我认为最好的方法是始终将对象作为 UTC 传递,并在客户端上转换为本地时间。通过这样做,所有客户都有一个共同的参考点。

要转换为 UTC,请对 DateTime 对象调用 ToUniversalTime。然后,在客户端上调用 ToLocalTime 以获取当前时区的时间。

其他提示

一个大问题是 WCF 序列化不支持 xs:Date。这是一个大问题,就好像您想要的只是一个约会,您不应该被迫关心时区。以下连接问题讨论了一些问题: http://connect.microsoft.com/wcf/feedback/ViewFeedback.aspx?FeedbackID=349215

如果你想明确地表示一个时间点,即不仅仅是日期部分,如果客户端和服务器上都有 .NET 3.5,则可以使用 DateTimeOffset 类。或者为了实现互操作性,始终将日期/时间值传递为 UTC。

UTC/GMT 在分布式环境中将保持一致。

一件重要的事情是,在使用数据库中的值填充 DateTime 属性后指定 datetimeKind。

dateTimeValueUtcKind = DateTime.SpecifyKind(dateTimeValue, DateTimeKind.Utc);

参见MSDN

只要您的 Web 服务层和客户端层使用 .NET DateTime 类型,它就应该正确序列化和反序列化为带有时区信息的 SOAP 标准本地日期/时间,例如:

09/15/2008 20:14:36

如果您绝对、肯定必须知道时区本身(即上面可能是东部标准时间或中部夏令时间),您需要创建自己的数据类型来公开这些片段:

[Serializable]
public sealed class MyDateTime
{
    public MyDateTime()
    {
        this.Now = DateTime.Now;
        this.IsDaylightSavingTime = this.Now.IsDaylightSavingTime();
        this.TimeZone = this.IsDaylightSavingTime
            ? System.TimeZone.CurrentTimeZone.DaylightName
            : System.TimeZone.CurrentTimeZone.StandardName;
    }

    public DateTime Now
    {
        get;

        set;
    }

    public string TimeZone
    {
        get;

        set;
    }

    public bool IsDaylightSavingTime
    {
        get;

        set;
    }
}

那么你的回应将如下所示:

<Now>2008-09-15T13:34:08.0039447-05:00</Now>
<TimeZone>Central Daylight Time</TimeZone>
<IsDaylightSavingTime>true</IsDaylightSavingTime>

我很幸运,只保留了 DateTime 数据类型并始终将其存储为 GMT。在每一层中,我会将 GMT 值调整为该层的本地值。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top