22

大约 4 年前,我关注了这篇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。:)

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

4

6 回答 6

19

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

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

于 2008-09-15T18:14:18.043 回答
12

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

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

于 2008-09-16T20:00:22.413 回答
4

UTC/GMT 在分布式环境中是一致的。

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

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

见 MSDN

于 2008-09-16T07:53:31.770 回答
2

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

2008-09-15T13:14:36.9502109-05:00

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

[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>
于 2008-09-15T18:34:59.240 回答
1

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

于 2008-09-15T18:21:13.267 回答
0

对于日期时间对象应该保持不变的情况,请使用 JsonConvert:

DateTime now = DateTime.Now;
string json = JsonConvert.SerializeObject(now);
DateTime nowJson = JsonConvert.DeserializeObject<DateTime>(json);
于 2020-11-30T10:11:46.503 回答