本文介绍了System.DateTime.Now和System.DateTime.Today之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人都可以解释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之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 15:04