任何人都可以解释 C#.NET 中的System.DateTime.Now
和System.DateTime.Today
之间的区别吗?
DateTime.Now
返回一个DateTime
值,该值由运行代码的计算机的本地日期和时间组成。它的Kind
属性分配有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
值,该值具有与上述任何表达式相同的年,月和日分量,但时间分量设置为零。它的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
。但是它是谁的本地呢?一旦您使用该值执行任何操作,这些信息就会丢失,例如将其存储在数据库中,在屏幕上显示或使用服务传输它。
如果您的本地时区遵循任何夏令时规则。您不会从DateTime.Now
中的某个时间返回该信息。在不明确的时间,例如在“回退”过渡期间,您将不知道两个可能的时刻中的哪个对应于您使用DateTime.Now
检索的值。例如,假设您的系统时区设置为Mountain Time (US & Canada)
,并且您要求0
你可以做的最好的事情是使用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。
另外,在这个世界上有一些地方(例如巴西),“spring-forward”转换发生在午夜。时钟从 23:59 到 01:00。这意味着您在该日期获得的DateTime.Today
值不存在!
如果你真的想要一个完全正确的解决这个问题,最好的方法是使用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 feed 中找到System.Time
包对象。一旦添加到你的项目中,你会发现你可以执行以下任何操作:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);

时间。.Now
包括 09:23:12 或其他;.Today
仅是日期部分(当天 00:00:00)。
所以使用.Now
如果你想包括时间,和.Today
如果你只是想要的日期!
.Today
与.Now.Date
基本相同
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;
}
}
本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处
评论列表(14条)