.net DateTime.Now 与 DateTime.UtcNow

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/62151/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 09:50:39  来源:igfitidea点击:

DateTime.Now vs. DateTime.UtcNow

.netlanguage-featuresdate

提问by Slavo

I've been wondering what exactly are the principles of how the two properties work. I know the second one is universal and basically doesn't deal with time zones, but can someone explain in detail how they work and which one should be used in what scenario?

我一直想知道这两个属性的工作原理究竟是什么。我知道第二个是通用的,基本上不涉及时区,但有人可以详细解释它们是如何工作的,以及应该在什么场景下使用哪个?

回答by Blair Conrad

DateTime.UtcNowtells you the date and time as it would be in Coordinated Universal Time, which is also called the Greenwich Mean Time time zone - basically like it would be if you were in London England, but not during the summer. DateTime.Nowgives the date and time as it would appear to someone in your current locale.

DateTime.UtcNow告诉您协调世界时的日期和时间,也称为格林威治标准时间时区 - 基本上就像您在英国伦敦时一样,但不是在夏季。DateTime.Now提供日期和时间,因为它在您当前的语言环境中显示给某人。

I'd recommend using DateTime.Nowwhenever you're displaying a date to a human being - that way they're comfortable with the value they see - it's something that they can easily compare to what they see on their watch or clock. Use DateTime.UtcNowwhen you want to store dates or use them for later calculations that way (in a client-server model) your calculations don't become confused by clients in different time zones from your server or from each other.

我建议DateTime.Now您在向他人显示日期时使用 - 这样他们就会对他们看到的价值感到满意 - 他们可以轻松地将其与他们在手表或时钟上看到的内容进行比较。使用DateTime.UtcNow时要存储日期或将其用于以后计算这样(在客户机-服务器模式)你的计算不要被从你的服务器或彼此不同的时区的客户混淆。

回答by Jeff Atwood

It's really quite simple, so I think it depends what your audience is and where they live.

这真的很简单,所以我认为这取决于你的观众是什么以及他们住在哪里。

If you don't use Utc, you mustknow the timezone of the person you're displaying dates and times to -- otherwise you will tell them something happened at 3 PM in system or server time, when it really happened at 5 PM where they happen to live.

如果你不使用 Utc,你必须知道你显示日期和时间的人的时区——否则你会告诉他们在系统或服务器时间下午 3 点发生的事情,当它真正发生在下午 5 点时他们碰巧活着。

We use DateTime.UtcNowbecause we have a global web audience, and because I'd prefer not to nag every user to fill out a form indicating what timezone they live in.

我们使用它DateTime.UtcNow是因为我们拥有全球网络受众,而且因为我不希望每个用户都在填写表格以表明他们居住在哪个时区。

We also display relative times (2 hours ago, 1 day ago, etc) until the post ages enough that the time is "the same" no matter where on Earth you live.

我们还显示相对时间(2 小时前、1 天前等),直到帖子年龄足够大,无论您住在地球上的哪个地方,时间都是“相同的”。

回答by Magnus Krisell

Also note the performance difference; DateTime.UtcNowis somewhere around 30times faster then DateTime.Now, because internally DateTime.Nowis doing a lot of timezone adjustments (you can easily verify this with Reflector).

还要注意性能差异;DateTime.UtcNow大约快30DateTime.Now,因为在内部DateTime.Now进行了很多时区调整(您可以使用 Reflector 轻松验证这一点)。

So do NOT use DateTime.Nowfor relative time measurements.

所以不要DateTime.Now用于相对时间测量。

回答by Carl Camera

One main concept to understand in .NET is that nowis nowall over the earth no matter what time zone you are in. So if you load a variable with DateTime.Nowor DateTime.UtcNow-- the assignment is identical.* Your DateTimeobject knows what timezone you are in and takes that into account regardless of the assignment.

一个主要的概念在.NET难以理解的是,现在现在地球上各地不论你是在那么什么时区,如果您加载一个变量,DateTime.NowDateTime.UtcNow-分配是相同的*您DateTime对象知道什么时区你是在并考虑到这一点,无论分配如何。

The usefulness of DateTime.UtcNowcomes in handy when calculating dates across Daylight Savings Time boundaries. That is, in places that participate in daylight savings time, sometimes there are 25 hours from noon to noon the following day, and sometimes there are 23 hours between noon and noon the following day. If you want to correctly determine the number of hours from time A and time B, you need to first translate each to their UTC equivalents before calculating the TimeSpan.

DateTime.UtcNow在跨夏令时边界计算日期时,的用处会派上用场。即在实行夏令时的地方,有时从中午到次日中午有25小时,有时从中午到次日中午有23小时。如果您想正确确定时间 A 和时间 B 之间的小时数,您需要在计算TimeSpan.

This is covered by a blog post i wrotethat further explains TimeSpan, and includes a link to an even more extensive MS article on the topic.

我写一篇博客文章对此进行了进一步解释TimeSpan,并包含指向有关该主题的更广泛的 MS 文章的链接。

*Clarification: Either assignment will store the current time. If you were to load two variables one via DateTime.Now()and the other via DateTime.UtcNow()the TimeSpandifference between the two would be milliseconds, not hours assuming you are in a timezone hours away from GMT. As noted below, printing out their Stringvalues would display different strings.

*说明:任一分配都将存储当前时间。如果您要加载两个变量,一个通过DateTime.Now(),另一个通过两者之间DateTime.UtcNow()TimeSpan差异将是毫秒,而不是假设您在距格林威治标准时间数小时的时区中的小时数。如下所述,打印出它们的String值会显示不同的字符串。

回答by Ted Bigham

This is a good question. I'm reviving it to give a little more detail on how .Net behaves with different Kindvalues. As @Jan Zich points out, It's actually a critically important property and is set differently depending on whether you use Nowor UtcNow.

这是一个很好的问题。我正在恢复它,以提供有关 .Net 如何处理不同Kind值的更多细节。作为@Jan Zich指出,这实际上是一个非常重要的属性,并设置不同,这取决于您是否使用NowUtcNow

Internally the date is stored as Tickswhich (contrary to @Carl Camera's answer) is different depending on if you use Nowor UtcNow.

日期在内部存储为Ticks(与@Carl Camera 的答案相反)根据您是否使用Now或不同而不同UtcNow

DateTime.UtcNowbehaves like other languages. It sets Ticksto a GMT based value. It also sets Kindto Utc.

DateTime.UtcNow行为与其他语言一样。它设置Ticks为基于 GMT 的值。它也设置KindUtc

DateTime.Nowalters the Ticksvalue to what it would be if it was your time of day in the GMT time zone. It also sets Kindto Local.

DateTime.NowTicks值更改为GMT 时区中您一天中的时间。它也设置KindLocal

If you're 6 hours behind (GMT-6), you'll get the GMT time from 6 hours ago. .Net actually ignores Kindand treats this time as if it was 6 hours ago, even though it's supposed to be "now". This breaks even more if you create a DateTimeinstance then change your time zone and try to use it.

如果您晚了 6 小时 (GMT-6),您将获得 6 小时前的 GMT 时间。.Net 实际上忽略了Kind这个时间并将其视为 6 小时前,即使它应该是“现在”。如果您创建一个DateTime实例然后更改您的时区并尝试使用它,这会破坏更多。

DateTime instances with different 'Kind' values are NOT compatible.

具有不同“种类”值的 DateTime 实例不兼容。

Let's look at some code...

让我们看一些代码...

    DateTime utc = DateTime.UtcNow;
    DateTime now = DateTime.Now;
    Debug.Log (utc + " " + utc.Kind);  // 05/20/2015 17:19:27 Utc
    Debug.Log (now + " " + now.Kind);  // 05/20/2015 10:19:27 Local

    Debug.Log (utc.Ticks);  // 635677391678617830
    Debug.Log (now.Ticks);  // 635677139678617840

    now = now.AddHours(1);
    TimeSpan diff = utc - now;
    Debug.Log (diff);  // 05:59:59.9999990

    Debug.Log (utc <  now);  // false
    Debug.Log (utc == now);  // false
    Debug.Log (utc >  now);  // true

    Debug.Log (utc.ToUniversalTime() <  now.ToUniversalTime());  // true
    Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() >  now.ToUniversalTime());  // false
    Debug.Log (utc.ToUniversalTime() -  now.ToUniversalTime());  // -01:00:00.0000010

As you can see here, comparisons and math functions don't automatically convert to compatible times. The Timespanshould have been almost one hour, but instead was almost 6. "utc < now" should have been true (I even added an hour to be sure), but was still false.

正如您在此处看到的,比较和数学函数不会自动转换为兼容时间。本Timespan应该已经差不多一小时,而是几乎6.“UTC <现在”应该是真实的(我甚至增加了一小时,以确保),但仍然是假的。

You can also see the 'work around' which is to simply convert to universal time anywhere that Kindis not the same.

您还可以看到“解决方法”,即在任何Kind不相同的地方简单地转换为世界时。

My direct answer to the question agrees with the accepted answer's recommendation about when to use each one. You should always tryto work with DateTimeobjects that have Kind=Utc, except during i/o (displaying and parsing). This means you should almost always be using DateTime.UtcNow, except for the cases where you're creating the object just to display it, and discard it right away.

我对这个问题的直接回答与接受的答案关于何时使用每个答案的建议一致。您应该始终尝试使用具有 的DateTime对象Kind=Utc,但在 i/o(显示和解析)期间除外。这意味着您应该几乎总是使用DateTime.UtcNow,除非您创建对象只是为了显示它,然后立即丢弃它。

回答by Omer van Kloeten

DateTime has no idea what time zones are. It always assumes you're at your local time. UtcNowonly means "Subtract my timezone from the time".

DateTime 不知道时区是什么。它始终假设您在当地时间。UtcNow仅表示“从时间中减去我的时区”。

If you want to use timezone-aware dates, use DateTimeOffset, which represents a date/time with a timezone. I had to learn that the hard way.

如果要使用时区感知日期,请使用DateTimeOffset,它表示带有时区的日期/时间。我必须以艰难的方式学习。

回答by PapillonUK

The "simple" answer to the question is:

这个问题的“简单”答案是:

DateTime.Nowreturns a DateTimevalue representing the current, system time (in whatever time zone the system is running in). The DateTime.Kindproperty will be DateTimeKind.Local

DateTime.Now返回一个DateTime值,表示当前的系统时间(系统运行所在的任何时区)。该DateTime.Kind属性将为DateTimeKind.Local

DateTime.UtcNowreturns a DateTimevalue representing the current Universal Co-ordinated Time (aka UTC) which will be the same regardless of the system's time zone. The DateTime.Kindproperty will be DateTimeKind.Utc

DateTime.UtcNow返回一个DateTime值,表示当前的通用协调时间(又名 UTC),无论系统的时区如何,该值都是相同的。该DateTime.Kind属性将为DateTimeKind.Utc

回答by Jan Zich

Just a little addition to the points made above: the DateTime struct also contains a little known field called Kind(at least, I did not know about it for a long time). It is basically just a flag indicating whether the time is local or UTC; it does not specify the real offset from UTC for local times. Besides the fact that it indicates with what intentions the stuct was constructed, it also influences the way how the methods ToUniversalTime()and ToLocalTime()work.

只是对上面提出的几点补充一点:DateTime 结构还包含一个鲜为人知的字段,称为Kind(至少,我很长时间不知道它)。它基本上只是一个指示时间是本地时间还是UTC时间的标志;它没有指定本地时间与 UTC 的实际偏移量。除了它表明结构的构建意图之外,它还影响ToUniversalTime()ToLocalTime() 方法的工作方式。

回答by Sorin Comanescu

A little bit late to the party, but I found these two links (4guysfromrolla) to be very useful:

聚会有点晚,但我发现这两个链接 (4guysfromrolla) 非常有用:

Using Coordinated Universal Time (UTC) to Store Date/Time Values

使用协调世界时 (UTC) 存储日期/时间值

Advice for Storing and Displaying Dates and Times Across Different Time Zones

跨时区存储和显示日期和时间的建议

回答by user1315023

DateTime.UtcNow is a continuous, single-valued time scale, whereas DateTime.Now is not continuous or single-valued. The primary reason is Daylight Savings Time, which doesn't apply to UTC. So UTC never jumps forward or back an hour, whereas local time(DateTime.Now) does. And when it jumps backward, the same time value occurs twice.

DateTime.UtcNow 是一个连续的、单值的时间尺度,而 DateTime.Now 不是连续的或单值的。主要原因是夏令时,它不适用于 UTC。所以 UTC 永远不会向前或向后跳跃一个小时,而本地时间(DateTime.Now)会。当它向后跳时,相同的时间值出现两次。