问题描述
任何人都可以解释C#.NET中的 System.DateTime.Now
和 System.DateTime.Today
之间的区别?
DateTime.Now
返回一个 DateTime
值,由代码运行的计算机的本地日期和时间组成。 $ DateTimeKind.Local
分配给其种类
属性。相当于调用以下任何一项:
-
DateTime.UtcNow.ToLocalTime()
-
DateTimeOffset.UtcNow.LocalDateTime
-
DateTimeOffset。 Now.LocalDateTime
-
TimeZoneInfo.ConvertTime(DateTime.UtcNow,TimeZoneInfo.Local)
-
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow,TimeZoneInfo.Local)
DateTime.Today
返回一个具有相同年,月和日组件的 DateTime
值任何上述表达式,但与时间组件设置为零。在种类
属性中,它还具有 DateTimeKind.Local
。相当于以下任何一项:
-
DateTime.Now.Date
/ li>
-
DateTime.UtcNow.ToLocalTime()。Date
-
DateTimeOffset .UtcNow.LocalDateTime.Date
-
DateTimeOffset.Now.LocalDateTime.Date
-
TimeZoneInfo.ConvertTime(DateTime.UtcNow,TimeZoneInfo.Local).Date
-
TimeZoneInfo .ConvertTimeFromUtc(DateTime.UtcNow,TimeZoneInfo.Local).Date
请注意,内部系统时钟是UTC的,所以当你调用 DateTime.Now
它首先得到UTC时间(通过函数),然后转换值到当地时区。 (因此 DateTime.Now.ToUniversalTime()
比 DateTime.UtcNow
更贵)。
另请注意, DateTimeOffset.Now.DateTime
将具有类似于 DateTime.Now
,但它将具有 DateTimeKind.Unspecified
而不是 DateTimeKind.Local
- 这可能导致其他错误,具体取决于什么所以,简单的答案是 DateTime.Today
相当于 DateTime.Now.Date
。
但是,IMHO - 您不应该使用这些或任何上述等价物之一。 / p>
当您要求 DateTime.Now
时,您将要求计算机的本地日历时钟的值代码正在运行。但是你回来的没有关于那个时钟的任何信息!你得到的最好的是 DateTime.Now.Kind == DateTimeKind.Local
。但他们的地方呢?一旦您做任何有价值的信息,即可将信息丢失,例如将其存储在数据库中,将其显示在屏幕上或使用Web服务进行传输。
如果您的本地时区遵循任何夏令时规则,则您不会从 DateTime.Now
中获取该信息。在不明确的时候,例如在倒退过渡期间,您不会知道两个可能的时刻中哪一个与您通过 DateTime.Now
检索到的值相对应。例如,假设您的系统时区设置为 Mountain Time(US& Canada)
,并且您要求 DateTime.Now
在2013年11月3日的初期。结果 2013-11-03 01:00:00
是什么意思?瞬时时间有两个时刻由同一个日历时间表示。如果我把这个价值交给别人,他们就不知道我的意思。特别是如果它们在规则不同的时区。
最好的事情是使用 DateTimeOffset
代替:
//这将永远是明确的。
DateTimeOffset now = DateTimeOffset.Now;
现在对于上述我所说的相同情况,我得到的价值 2013- 11-03 01:00:00 -0600
转换前,或$ code> 2013-11-03 01:00:00 -0700 转换后。任何看这些价值观的人都可以告诉我的意思。
我在这个主题上写了一篇博文。请阅读 - 的案例。
此外,这个世界上还有一些地方(如巴西),春天转型恰好在午夜。时钟从23:59到01:00。这意味着您在该日期的 DateTime.Today
获得的值不存在!即使您使用 DateTimeOffset .Now.Date
,你得到的结果相同,你仍然有这个问题。这是因为传统上,在.Net中没有一个 Date
对象。所以无论你如何获得价值,一旦你脱离时间 - 你必须记住,它并不代表午夜,即使这是你正在使用的价值。
如果您真的想要一个完全正确的解决方案来解决这个问题,最好的方法是使用。 LocalDate
类正确表示一个没有时间的日期。您可以获取任何时区的当前日期,包括本地系统时区:
使用NodaTime;
...
立即即时= SystemClock.Instance.Now;
DateTimeZone zone1 = DateTimeZoneProviders.Tzdb.GetSystemDefault();
LocalDate todayInTheSystemZone = now.InZone(zone1).Date;
DateTimeZone zone2 = DateTimeZoneProviders.Tzdb [America / New_York];
LocalDate todayInTheOtherZone = now.InZone(zone2).Date;
如果您不想使用Noda Time,现在还有另一个选项。我已经为项目贡献了一个日期对象的实现。您可以在其MyGet Feed中找到 System.Time
包对象。一旦添加到您的项目中,您将发现可以执行以下操作:
using System;
...
日期localDate = Date.Today;
日期utcDate = Date.UtcToday;
日期tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
Can anyone explain the difference between System.DateTime.Now
and System.DateTime.Today
in C#.NET? Pros and cons of each if possible.
DateTime.Now
returns a DateTime
value that consists of the local date and time of the computer where the code is running. It has DateTimeKind.Local
assigned to its Kind
property. It is equivalent to calling any of the following:
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today
returns a DateTime
value that has the same year, month, and day components as any of the above expressions, but with the time components set to zero. It also has DateTimeKind.Local
in its Kind
property. It is equivalent to any of the following:
DateTime.Now.Date
DateTime.UtcNow.ToLocalTime().Date
DateTimeOffset.UtcNow.LocalDateTime.Date
DateTimeOffset.Now.LocalDateTime.Date
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local).Date
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local).Date
Note that internally, the system clock is in terms of UTC, so when you call DateTime.Now
it first gets the UTC time (via the GetSystemTimeAsFileTime
function in the Win32 API) and then it converts the value to the local time zone. (Therefore DateTime.Now.ToUniversalTime()
is more expensive than DateTime.UtcNow
.)
Also note that DateTimeOffset.Now.DateTime
will have similar values to DateTime.Now
, but it will have DateTimeKind.Unspecified
rather than DateTimeKind.Local
- which could lead to other errors depending on what you do with it.
So, the simple answer is that DateTime.Today
is equivalent to DateTime.Now.Date
.
But IMHO - You shouldn't use either one of these, or any of the above equivalents.
When you ask for DateTime.Now
, you are asking for the value of the local calendar clock of the computer that the code is running on. But what you get back does not have any information about that clock! The best that you get is that DateTime.Now.Kind == DateTimeKind.Local
. But whose local is it? That information gets lost as soon as you do anything with the value, such as store it in a database, display it on screen, or transmit it using a web service.
If your local time zone follows any daylight savings rules, you do not get that information back from DateTime.Now
. In ambiguous times, such as during a "fall-back" transition, you won't know which of the two possible moments correspond to the value you retrieved with DateTime.Now
. For example, say your system time zone is set to Mountain Time (US & Canada)
and you ask for DateTime.Now
in the early hours of November 3rd, 2013. What does the result 2013-11-03 01:00:00
mean? There are two moments of instantaneous time represented by this same calendar datetime. If I were to send this value to someone else, they would have no idea which one I meant. Especially if they are in a time zone where the rules are different.
The best thing you could do would be to use DateTimeOffset
instead:
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Now for the same scenario I described above, I get the value 2013-11-03 01:00:00 -0600
before the transition, or 2013-11-03 01:00:00 -0700
after the transition. Anyone looking at these values can tell what I meant.
I wrote a blog post on this very subject. Please read - The Case Against DateTime.Now.
Also, there are some places in this world (such as Brazil) where the "spring-forward" transition happens exactly at Midnight. The clocks go from 23:59 to 01:00. This means that the value you get for DateTime.Today
on that date, does not exist! Even if you use DateTimeOffset.Now.Date
, you are getting the same result, and you still have this problem. It is because traditionally, there has been no such thing as a Date
object in .Net. So regardless of how you obtain the value, once you strip off the time - you have to remember that it doesn't really represent "midnight", even though that's the value you're working with.
If you really want a fully correct solution to this problem, the best approach is to use NodaTime. The LocalDate
class properly represents a date without a time. You can get the current date for any time zone, including the local system time zone:
using NodaTime;
...
Instant now = SystemClock.Instance.Now;
DateTimeZone zone1 = DateTimeZoneProviders.Tzdb.GetSystemDefault();
LocalDate todayInTheSystemZone = now.InZone(zone1).Date;
DateTimeZone zone2 = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDate todayInTheOtherZone = now.InZone(zone2).Date;
If you don't want to use Noda Time, there is now another option. I've contributed an implementation of a date-only object to the .Net CoreFX Lab project. You can find the System.Time
package object in their MyGet feed. Once added to your project, you will find you can do any of the following:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
这篇关于System.DateTime.Now和System.DateTime.Today之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!