将.NET DateTime值保留在客户端中指定的服务器中

时间:2014-10-20 13:42:14

标签: .net wpf wcf datetime timezone

在我的 WPF .NET客户端应用程序中,我为DateTime变量分配当前时间值:

class MyClass
{
  public DateTime CreatedDate {get; set;}
}

MyClass myClass = new MyClass();
myClass.CreatedDate = DateTime.Now;

在分配之后,我将对象发送到位于欧洲的 WCF服务(UTC + 1),该对象将对象保存在数据库中。如果客户端和服务位于同一个TimeZone,则没有问题。但是,如果我更改TimeZone,例如我的客户端在(UTC-6)和服务在(UCT + 1),服务将读取CreatedDate值,因为它是服务上的DateTime.Now(UCT + 1)代替客户端分配的(UCT-6)。如果在客户端(UTC-6)31/10/2014 20:00 上设置CreatedDate,它将被存储为(UTC + 1)01/11/2014在01:00 ,这会影响我系统上的某些进程。

这不是我想要的行为,我希望服务始终存储客户提交的日期。

我可以访问服务器和客户端的代码,我在设置CreatedDate时尝试设置为:

myClass.CreatedDate = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);
没有运气。我能想到的唯一解决方案是使用字符串而不是DateTime,但这意味着代码中有很多变化。有人知道如何忽略TimeZone设置吗?

1 个答案:

答案 0 :(得分:4)

您有几种不同的选择:

  • 将所有内容保留为DateTime,但使用UTC值而不是本地值。这意味着使用DateTime.UtcNow来获取当前时间。

    在客户端上,您可以使用ToLocalTime生成显示值,以将UTC中的值转换为运行客户端代码的计算机的本地时区。

  • 切换到DateTimeOffset。这确保了在将值从客户端传输到服务器时保留时区偏移量 - 这可以告诉您特定时间戳与UTC的距离。

    您可以使用 <{em> DateTimeOffset.UtcNowDateTimeOffset.Now获取当前时间。后者具有保留当地时间的优点,因为客户理解它。如果您计划根据本地日期/时间对数据进行任何汇总分析,那么您将需要此信息。请记住,“今天”对于地球上的每个人来说都是不一样的。

  • 如果您有另一种方式来传达客户的时区,或者您已经从外部信息中知道了这一点,那么您可以传输 一个DateTime或者DateTimeOffset,然后使用TimeZoneInfo类在服务器上进行转换。

    然而,有一个“陷阱”。如果您传输的{em>本地
    DateTime处于daylight saving time歧义期(在“后退”过渡期间),那么您可能会错误地转换。使用UTC或DateTimeOffset可以避免此问题。

另请参阅The Case Against DateTime.NowDateTime vs DateTimeOffset