Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DateTime vs DateTimeOffset_C#_.net_Datetime_Timezone_Datetimeoffset - Fatal编程技术网

C# DateTime vs DateTimeOffset

C# DateTime vs DateTimeOffset,c#,.net,datetime,timezone,datetimeoffset,C#,.net,Datetime,Timezone,Datetimeoffset,目前,我们有一种以时区感知方式处理.NETDateTime的标准方法:每当我们生成一个DateTime时,我们都使用UTC(例如,使用DateTime.UtcNow),每当我们显示一个时,我们就从UTC转换回用户的本地时间 这很好,但我一直在阅读有关DateTimeOffset以及它如何捕获对象本身中的本地时间和UTC时间的内容。所以问题是,与我们已经在做的事情相比,使用DateTimeOffset有什么好处?有一些地方DateTimeOffset是有意义的。一个是当你处理重复发生的事件和夏令时

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


这很好,但我一直在阅读有关
DateTimeOffset
以及它如何捕获对象本身中的本地时间和UTC时间的内容。所以问题是,与我们已经在做的事情相比,使用
DateTimeOffset
有什么好处?

有一些地方
DateTimeOffset
是有意义的。一个是当你处理重复发生的事件和夏令时。比如说,我想把闹钟设置为每天早上9点响。如果我使用“存储为UTC,显示为本地时间”规则,则当夏令时生效时,警报将在不同的时间发出


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

一个主要区别是
日期时间偏移量
可以与
时区信息
结合使用,以转换为当前时区以外的时区中的本地时间


这在由不同时区的用户访问的服务器应用程序(例如ASP.NET)上很有用。

DateTime只能存储两个不同的时间,即本地时间和UTC。Kind属性指示哪个时间

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

t:

DateTimeOffset值的这些用法比DateTime值的用法更常见。因此,DateTimeOffset应被视为应用程序开发的默认日期和时间类型

资料来源:,MSDN

当我们的应用程序处理特定的时间点(例如,当创建/更新记录时),我们几乎对所有事情都使用
DateTimeOffset
。作为补充说明,我们在SQL Server 2008中也使用
DateTimeOffset

我认为
DateTime
对于只处理日期、只处理时间或一般意义上的任何一种情况都很有用。例如,如果您有一个闹钟,希望每天早上7点响,您可以使用
未指定的
DateTimeKind
将其存储在
DateTime
中,因为您需要它无论DST如何,都会在上午7点发出警报。但如果要表示警报发生的历史记录,可以使用
DateTimeOffset


混合使用
DateTimeOffset
DateTime
时要小心,尤其是在类型之间分配和比较时。此外,只比较与
DateTimeKind
相同的
DateTimeKind
实例,因为
DateTime
在比较时忽略时区偏移。

DateTimeOffset
是瞬时时间(也称为绝对时间)的表示法。我指的是对每个人都通用的时间瞬间(不考虑时间的相对论效应)。另一种表示瞬时时间的方法是使用
DateTime
,其中
.Kind
DateTimeKind.Utc

这与日历时间(也称为民用时间)不同,这是某人日历上的一个位置,全球有许多不同的日历。我们称这些日历为时区。日历时间由
日期时间
表示,其中
.Kind
日期时间种类。未指定的
,或
日期时间种类.Local
.Local
仅在s中有意义cenarios,您对使用结果的计算机的位置有隐含的理解。(例如,用户的工作站)

那么,为什么要使用
DateTimeOffset
而不是UTC
DateTime
这一切都是关于透视。让我们用一个类比——我们将假装是摄影师

想象一下,你站在日历时间线上,将相机指向摆在你面前的即时时间线上的一个人。你根据时区规则排列相机。由于夏令时或时区法律定义的其他变化,时区规则会定期变化。(你的手不稳,所以你的相机不稳。)

站在照片中的人会看到你的相机的角度。如果其他人在拍照,他们可能来自不同的角度。这就是
DateTimeOffset
部分的
Offset所代表的角度

因此,如果你将你的相机标为“东部时间”,有时你从-5指向,有时你从-4指向。世界各地都有相机,都标上了不同的东西,都从不同的角度指向同一个瞬时时间轴。其中一些相机就在旁边(或上方)因此,仅仅知道偏移量不足以确定时间与哪个时区相关

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