DateTime和DateTimeOffset之间的区别是什么,什么时候应该使用?


目前,我们有一种以时区感知的方式处理. net DateTime的标准方法:每当我们生成一个DateTime时,我们都使用UTC(例如使用DateTime. utcnow),每当我们显示一个DateTime时,我们从UTC转换回用户的本地时间。

这很好,但我已经阅读了DateTimeOffset以及它如何捕获对象本身的本地时间和UTC时间。


当前回答

微软的这段代码解释了一切:

// Find difference between Date.Now and Date.UtcNow
  date1 = DateTime.Now;
  date2 = DateTime.UtcNow;
  difference = date1 - date2;
  Console.WriteLine("{0} - {1} = {2}", date1, date2, difference);

  // Find difference between Now and UtcNow using DateTimeOffset
  dateOffset1 = DateTimeOffset.Now;
  dateOffset2 = DateTimeOffset.UtcNow;
  difference = dateOffset1 - dateOffset2;
  Console.WriteLine("{0} - {1} = {2}", 
                    dateOffset1, dateOffset2, difference);
  // If run in the Pacific Standard time zone on 4/2/2007, the example
  // displays the following output to the console:
  //    4/2/2007 7:23:57 PM - 4/3/2007 2:23:57 AM = -07:00:00
  //    4/2/2007 7:23:57 PM -07:00 - 4/3/2007 2:23:57 AM +00:00 = 00:00:00

其他回答

微软的这段代码解释了一切:

// Find difference between Date.Now and Date.UtcNow
  date1 = DateTime.Now;
  date2 = DateTime.UtcNow;
  difference = date1 - date2;
  Console.WriteLine("{0} - {1} = {2}", date1, date2, difference);

  // Find difference between Now and UtcNow using DateTimeOffset
  dateOffset1 = DateTimeOffset.Now;
  dateOffset2 = DateTimeOffset.UtcNow;
  difference = dateOffset1 - dateOffset2;
  Console.WriteLine("{0} - {1} = {2}", 
                    dateOffset1, dateOffset2, difference);
  // If run in the Pacific Standard time zone on 4/2/2007, the example
  // displays the following output to the console:
  //    4/2/2007 7:23:57 PM - 4/3/2007 2:23:57 AM = -07:00:00
  //    4/2/2007 7:23:57 PM -07:00 - 4/3/2007 2:23:57 AM +00:00 = 00:00:00

在一些地方,DateTimeOffset是有意义的。一种是处理重复事件和夏时制时。假设我想设置一个闹钟,让它每天早上9点响。如果我使用“存储为UTC,显示为本地时间”规则,那么当夏令时生效时,闹钟将在不同的时间响起。

可能还有其他的例子,但上面的例子实际上是我过去遇到的一个(这是在将DateTimeOffset添加到BCL之前-我当时的解决方案是显式地将时间存储在本地时区,并将时区信息保存在旁边:基本上是DateTimeOffset内部做的事情)。

一个主要的区别是DateTimeOffset可以与TimeZoneInfo一起使用,以转换为当前时区以外的本地时间。

这对于由不同时区的用户访问的服务器应用程序(例如ASP.NET)非常有用。

DateTime只能存储两个不同的时间,本地时间和UTC。Kind属性指明是哪一种。

DateTimeOffset在此基础上进行了扩展,它能够存储世界上任何地方的本地时间。它还存储本地时间与UTC之间的偏移量。请注意DateTime无法做到这一点,除非您向类中添加一个额外的成员来存储UTC偏移量。或者只使用UTC。顺便说一句,这本身就是个好主意。

我认为DateTimeOffset唯一的缺点是微软“忘记”(故意)在他们的XmlSerializer类中支持它。但是它已经被添加到XmlConvert实用程序类中。

XmlConvert。ToDateTimeOffset

XmlConvert。ToString

我建议继续使用DateTimeOffset和TimeZoneInfo,因为它们都有好处,只是在创建将或可能序列化到XML或从XML序列化的实体时要小心(那时都是业务对象)。