DateTime和DateTimeOffset之间的区别是什么,什么时候应该使用?
目前,我们有一种以时区感知的方式处理. net DateTime的标准方法:每当我们生成一个DateTime时,我们都使用UTC(例如使用DateTime. utcnow),每当我们显示一个DateTime时,我们从UTC转换回用户的本地时间。
这很好,但我已经阅读了DateTimeOffset以及它如何捕获对象本身的本地时间和UTC时间。
DateTime和DateTimeOffset之间的区别是什么,什么时候应该使用?
目前,我们有一种以时区感知的方式处理. net DateTime的标准方法:每当我们生成一个DateTime时,我们都使用UTC(例如使用DateTime. utcnow),每当我们显示一个DateTime时,我们从UTC转换回用户的本地时间。
这很好,但我已经阅读了DateTimeOffset以及它如何捕获对象本身的本地时间和UTC时间。
当前回答
从微软:
DateTimeOffset值的这些用法比DateTime值的用法更常见。因此,应该将DateTimeOffset视为应用程序开发的默认日期和时间类型。
来源:“选择DateTime, DateTimeOffset, TimeSpan和TimeZoneInfo”,MSDN
当我们的应用程序处理特定的时间点时(例如,当一个记录被创建/更新时),我们几乎所有的事情都使用DateTimeOffset。顺便说一句,我们在SQL Server 2008中也使用了DATETIMEOFFSET。
我认为,当您只想处理日期、时间或在一般意义上处理这两种情况时,DateTime非常有用。例如,如果您有一个闹钟,希望每天早上7点响,您可以使用未指定的DateTimeKind将其存储在DateTime中,因为您希望它在早上7点响,而不考虑夏令时。但是,如果希望表示告警发生的历史,则可以使用DateTimeOffset。
在混合使用DateTimeOffset和DateTime时要谨慎,特别是在类型之间进行分配和比较时。同样,只比较DateTimeKind相同的DateTime实例,因为DateTime在比较时忽略了时区偏移。
其他回答
最重要的区别是DateTime不存储时区信息,而DateTimeOffset存储时区信息。
尽管DateTime区分UTC和Local,但绝对没有与之相关的显式时区偏移。如果执行任何类型的序列化或转换,将使用服务器的时区。即使您通过添加分钟来偏移UTC时间来手动创建本地时间,您仍然可以在序列化步骤中获得bit,因为(由于DateTime中没有任何显式偏移)它将使用服务器的时区偏移。
例如,如果你使用Json用Kind=Local序列化一个DateTime值。Net和ISO日期格式,你会得到一个像2015-08-05T07:00:00-04这样的字符串。注意最后一部分(-04)与你的DateTime或你用来计算它的任何偏移无关…这仅仅是服务器的时区偏移。
同时,DateTimeOffset显式地包含偏移量。它可能不包括时区的名称,但至少包括偏移量,如果序列化它,您将在值中获得显式包含的偏移量,而不是服务器的本地时间。
在一些地方,DateTimeOffset是有意义的。一种是处理重复事件和夏时制时。假设我想设置一个闹钟,让它每天早上9点响。如果我使用“存储为UTC,显示为本地时间”规则,那么当夏令时生效时,闹钟将在不同的时间响起。
可能还有其他的例子,但上面的例子实际上是我过去遇到的一个(这是在将DateTimeOffset添加到BCL之前-我当时的解决方案是显式地将时间存储在本地时区,并将时区信息保存在旁边:基本上是DateTimeOffset内部做的事情)。
一个主要的区别是DateTimeOffset可以与TimeZoneInfo一起使用,以转换为当前时区以外的本地时间。
这对于由不同时区的用户访问的服务器应用程序(例如ASP.NET)非常有用。
DateTime只能存储两个不同的时间,本地时间和UTC。Kind属性指明是哪一种。
DateTimeOffset在此基础上进行了扩展,它能够存储世界上任何地方的本地时间。它还存储本地时间与UTC之间的偏移量。请注意DateTime无法做到这一点,除非您向类中添加一个额外的成员来存储UTC偏移量。或者只使用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