System.DateTime.Now 和 System.DateTime.Today 之间的区别

Posted

技术标签:

【中文标题】System.DateTime.Now 和 System.DateTime.Today 之间的区别【英文标题】:Difference between System.DateTime.Now and System.DateTime.Today 【发布时间】:2011-09-26 13:53:23 【问题描述】:

谁能解释 C#.NET 中 System.DateTime.NowSystem.DateTime.Today 之间的区别?如果可能的话,各有优缺点。

【问题讨论】:

【参考方案1】:

时间。 .Now 包括 09:23:12 或其他; .Today 仅是日期部分(当天 00:00:00)。

因此,如果您想包含时间,请使用.Now,如果您只想包含日期,请使用.Today

.Today.Now.Date基本相同

【讨论】:

... 并使用UtcNow,除非您真的想要系统本地时区。 (尤其是在几乎总是错误选择的网络应用上。)【参考方案2】:

DateTime.Today表示当前系统日期,时间部分设置为00:00:00

DateTime.Now代表当前系统日期和时间

【讨论】:

只是一个观察... 1.1 文档远不如 4.0 文档详细;链接到 vLatest 可能更好? @megaperlz:您现在链接到 4.0 而不是 vLatest。删除(v=VS.100)即可制作最新链接。【参考方案3】:

DateTime.Now 属性返回当前日期和时间,例如2011-07-01 10:09.45310

DateTime.Today 属性返回当前日期,时间分量设置为零,例如2011-07-01 00:00.00000

DateTime.Today属性实际上是实现返回DateTime.Now.Date

public static DateTime Today 
  get 
    DateTime now = DateTime.Now;
    return now.Date;
  

【讨论】:

【参考方案4】:
DateTime dt = new DateTime();// gives 01/01/0001 12:00:00 AM
DateTime dt = DateTime.Now;// gives today date with current time
DateTime dt = DateTime.Today;// gives today date and 12:00:00 AM time

【讨论】:

【参考方案5】:

我想添加这些链接 -

A brief History of DateTime - By Anthony Moore by BCL team Choosing between Datetime and DateTime Offset - by MSDN Do not forget SQL server 2008 onwards has a new Datatype as DateTimeOffset .NET Framework 包括 DateTimeDateTimeOffsetTimeZoneInfo 类型,均可用于构建应用程序 适用于日期和时间。 Performing Arithmetic Operations with Dates and Times-MSDN

回到原来的问题,使用反射器我已经解释了代码的区别

 public static DateTime Today
    
      get
      
        return DateTime.Now.Date;   // It returns the date part of Now

        //Date Property
       // returns same date as this instance, and the time value set to 12:00:00 midnight (00:00:00) 
      
    


    private const long TicksPerMillisecond = 10000L;
    private const long TicksPerDay = 864000000000L;
    private const int MillisPerDay = 86400000;

    public DateTime Date
    
       get
      
        long internalTicks = this.InternalTicks; // Date this instance is converted to Ticks 
        return new DateTime((ulong) (internalTicks - internalTicks % 864000000000L) | this.InternalKind);  
// Modulo of TicksPerDay is subtracted - which brings the time to Midnight time 
      
    


     public static DateTime Now
        
          get
          
           /* this is why I guess Jon Skeet is recommending to use  UtcNow as you can see in one of the above comment*/
            DateTime utcNow = DateTime.UtcNow;


            /* After this i guess it is Timezone conversion */
            bool isAmbiguousLocalDst = false;
            long ticks1 = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousLocalDst).Ticks;
            long ticks2 = utcNow.Ticks + ticks1;
            if (ticks2 > 3155378975999999999L)
              return new DateTime(3155378975999999999L, DateTimeKind.Local);
            if (ticks2 < 0L)
              return new DateTime(0L, DateTimeKind.Local);
            else
              return new DateTime(ticks2, DateTimeKind.Local, isAmbiguousLocalDst);
          
        

【讨论】:

【参考方案6】:

DateTime.Now 返回一个DateTime 值,该值由运行代码的计算机的本地日期和时间组成。它已将 DateTimeKind.Local 分配给其 Kind 属性。相当于调用以下任何一个:

DateTime.UtcNow.ToLocalTime() DateTimeOffset.UtcNow.LocalDateTime DateTimeOffset.Now.LocalDateTime TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local) TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)

DateTime.Today 返回一个DateTime 值,该值具有与上述任何表达式相同的年、月和日分量,但时间分量设置为零。它的Kind 属性中也有DateTimeKind.Local。它等同于以下任何一种:

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

请注意,在内部,系统时钟以 UTC 表示,因此当您调用 DateTime.Now 时,它首先获取 UTC 时间(通过 Win32 API 中的 GetSystemTimeAsFileTime 函数),然后将值转换为本地时区。 (因此DateTime.Now.ToUniversalTime()DateTime.UtcNow 贵。)

另请注意,DateTimeOffset.Now.DateTime 将具有与 DateTime.Now 相似的值,但它将具有 DateTimeKind.Unspecified 而不是 DateTimeKind.Local - 这可能会导致其他错误,具体取决于您使用它的方式。

所以,简单的答案是 DateTime.Today 等同于 DateTime.Now.Date但是恕我直言 - 您不应该使用其中任何一个,或上述任何等效项。

当您询问DateTime.Now 时,您询问的是运行代码的计算机的本地日历时钟的值。但是你得到的并没有关于那个时钟的任何信息!你得到的最好的是DateTime.Now.Kind == DateTimeKind.Local。但它是谁的本地人?一旦您对该值进行任何操作(例如将其存储在数据库中、将其显示在屏幕上或使用 Web 服务传输),该信息就会丢失。

如果您的本地时区遵循任何夏令时规则,您将无法从DateTime.Now 获取该信息。在模棱两可的时期,例如在“回退”过渡期间,您将不知道两个可能时刻中的哪一个对应于您使用 DateTime.Now 检索到的值。例如,假设您的系统时区设置为 Mountain Time (US &amp; Canada),而您在 2013 年 11 月 3 日凌晨请求 DateTime.Now。结果 2013-11-03 01:00:00 是什么意思?同一日历日期时间表示两个瞬时时间时刻。如果我要将此值发送给其他人,他们将不知道我指的是哪一个。特别是如果他们处于规则不同的时区。

您可以做的最好的事情是使用DateTimeOffset

// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;

现在对于我上面描述的相同场景,我在转换之前得到值2013-11-03 01:00:00 -0600,或者在转换之后得到2013-11-03 01:00:00 -0700。任何看到这些值的人都能明白我的意思。

我就这个主题写了一篇博文。请阅读-The Case Against DateTime.Now。

此外,在这个世界上的某些地方(例如巴西),“弹簧向前”的过渡恰好发生在午夜。时钟从 23:59 到 01:00。这意味着您在该日期为DateTime.Today 获得的值,不存在!即使您使用DateTimeOffset.Now.Date,您得到相同的结果,您仍然有这个问题。这是因为传统上,.Net 中没有 Date 对象之类的东西。所以无论你如何获得价值,一旦你去掉时间——你必须记住它并不真正代表“午夜”,即使那是你正在使用的价值。

如果你真的想要一个完全正确的解决方案来解决这个问题,最好的方法是使用NodaTime。 LocalDate 类正确地表示没有时间的日期。您可以获取任何时区的当前日期,包括本地系统时区:

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;

如果您不想使用 Noda Time,现在还有另一种选择。我为.Net CoreFX Lab 项目贡献了一个仅日期对象的实现。您可以在他们的 MyGet 提要中找到 System.Time 包对象。添加到您的项目后,您会发现您可以执行以下任何操作:

using System;
...

Date localDate = Date.Today;

Date utcDate = Date.UtcToday;

Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);

【讨论】:

DateTime.UtcNow代替DateTimeOffset.Now怎么样? DateTime.UtcNow 是可以接受的,如果您可以在您的应用程序或规范中传达该值是 UTC 格式。 (我喜欢将字段或属性称为 MyDateUtc 而不仅仅是 MyDate - 但这只是锦上添花。)如果您无法在规范或字段名称中传达它,那么 DateTimeOffset.UtcNow 可以用于确保零偏移量与日期和时间值一起传达。 他们不相等。今天的时间是 00:00:00。 @JamesWilkins - 不知道你在做什么。 DateTime.Now.Date也是如此。 @MattJohnson 问题是问 DateTime.Today 和 DateTime.Now 之间的区别,而不是 DateTime.Today 和 DateTime.Now.Date。【参考方案7】:

DateTime.TodayDateTime.Now,时间设置为零。

请务必注意,DateTime 值(表示自 0000 年 1 月 1 日午夜以来经过的滴答数)与 DateTime 值的字符串表示(表示日期和时间)之间存在差异。特定文化格式的值: https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx

DateTime.Now.Ticks 是 .net 存储的实际时间(基本上是 UTC 时间),其余的只是 表示(这对于显示目的很重要)。

如果Kind 属性是DateTimeKind.Local,它隐含 包含本地计算机的时区信息。通过 .net Web 服务发送时,DateTime 值默认序列化,包括时区信息,例如2008-10-31T15:07:38.6875000-05:00,另一个时区的计算机仍然可以准确地知道所指的时间。

所以,使用 DateTime.Now 和 DateTime.Today 完全没问题。

当您开始将字符串表示与实际值混淆并尝试“修复”未损坏的 DateTime 时,您通常会遇到麻烦。

【讨论】:

【参考方案8】:

DateTime.Now.ToShortDateString() 将只显示日期部分

【讨论】:

以上是关于System.DateTime.Now 和 System.DateTime.Today 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

DateTime.Now.ToString()用法

System.DateTime.Now 24小时制。

System.DateTime.Now.ToString()的一些用法

C# 计算程序运行时间

C#计算一段程序运行时间的三种方法

string.Format 格式化输出日期