Bất cứ ai có thể giải thích sự khác biệt giữa System.DateTime.Now
và System.DateTime.Today
trong C# .NET? Ưu điểm và khuyết điểm của mỗi nếu có thể.Sự khác nhau giữa System.DateTime.Now và System.DateTime.Today
Trả lời
DateTime.Now
trả về một giá trị DateTime
đó bao gồm các ngày trong nước và thời gian của máy tính nơi đang chạy. Nó có DateTimeKind.Local
được gán cho thuộc tính Kind
của nó.Nó tương đương với gọi bất cứ điều nào sau đây:
DateTime.UtcNow.ToLocalTime()
DateTimeOffset.UtcNow.LocalDateTime
DateTimeOffset.Now.LocalDateTime
TimeZoneInfo.ConvertTime(DateTime.UtcNow, TimeZoneInfo.Local)
TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local)
DateTime.Today
trả về một giá trị DateTime
có cùng một năm, tháng, và các thành phần ngày như bất kỳ biểu thức nào ở trên, nhưng với các thành phần thời gian được đặt thành 0. Nó cũng có DateTimeKind.Local
trong thuộc tính Kind
của nó. Nó tương đương với bất kỳ những điều sau đây:
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
Lưu ý rằng nội bộ, đồng hồ hệ thống là về UTC, vì vậy khi bạn gọi DateTime.Now
nó lần đầu tiên nhận được thời gian UTC (thông qua hàm GetSystemTimeAsFileTime
trong API Win32) và sau đó nó chuyển đổi giá trị thành múi giờ địa phương. (Vì vậy DateTime.Now.ToUniversalTime()
đắt hơn DateTime.UtcNow
.)
Cũng lưu ý rằng DateTimeOffset.Now.DateTime
sẽ có giá trị tương tự như DateTime.Now
, nhưng nó sẽ có DateTimeKind.Unspecified
hơn DateTimeKind.Local
- điều này có thể dẫn đến sai sót khác tùy thuộc vào những gì bạn làm gì với nó.
Vì vậy, câu trả lời đơn giản là DateTime.Today
tương đương với DateTime.Now.Date
.
Nhưng IMHO - Bạn không nên sử dụng một trong hai thứ này hoặc bất kỳ điều nào tương đương ở trên.
Khi bạn yêu cầu DateTime.Now
, bạn đang yêu cầu giá trị của đồng hồ lịch địa phương của máy tính mà mã đang chạy. Nhưng những gì bạn nhận được trở lại không có bất kỳ thông tin về đồng hồ đó! Điều tốt nhất bạn nhận được là DateTime.Now.Kind == DateTimeKind.Local
. Nhưng có địa phương là nó? Thông tin đó sẽ bị mất ngay sau khi bạn làm bất cứ điều gì với giá trị, chẳng hạn như lưu trữ nó trong cơ sở dữ liệu, hiển thị nó trên màn hình hoặc truyền nó bằng dịch vụ web.
Nếu múi giờ địa phương của bạn tuân theo bất kỳ quy tắc tiết kiệm ánh sáng ban ngày nào, bạn không nhận được thông tin đó từ DateTime.Now
. Trong thời gian không rõ ràng, chẳng hạn như trong quá trình chuyển đổi "thu nhỏ", bạn sẽ không biết thời điểm nào trong hai khoảnh khắc có thể tương ứng với giá trị bạn đã truy xuất bằng DateTime.Now
. Ví dụ: giả sử múi giờ hệ thống của bạn được đặt thành Mountain Time (US & Canada)
và bạn yêu cầu DateTime.Now
vào đầu giờ ngày 3 tháng 11 năm 2013. Kết quả có nghĩa là gì 2013-11-03 01:00:00
? Có hai khoảnh khắc của thời gian tức thời được biểu thị bằng cùng một ngày giờ. Nếu tôi gửi giá trị này cho người khác, họ sẽ không biết tôi có ý gì. Đặc biệt là nếu họ ở trong một múi giờ nơi các quy tắc khác nhau.
Điều tốt nhất bạn có thể làm sẽ được sử dụng thay vì DateTimeOffset
:
// This will always be unambiguous.
DateTimeOffset now = DateTimeOffset.Now;
Bây giờ cho cùng một kịch bản tôi đã mô tả ở trên, tôi nhận được giá trị 2013-11-03 01:00:00 -0600
trước khi chuyển đổi, hoặc 2013-11-03 01:00:00 -0700
sau khi chuyển đổi. Bất cứ ai nhìn vào những giá trị này đều có thể nói những gì tôi muốn nói.
Tôi đã viết một bài đăng trên blog về chủ đề này. Vui lòng đọc - The Case Against DateTime.Now.
Ngoài ra, có một số địa điểm trên thế giới này (chẳng hạn như Brazil), nơi quá trình chuyển đổi "mùa xuân" diễn ra chính xác vào nửa đêm. Đồng hồ đi từ 23:59 đến 01:00. Điều này có nghĩa là giá trị bạn nhận được cho DateTime.Today
vào ngày đó, không tồn tại! Ngay cả khi bạn sử dụng DateTimeOffset.Now.Date
, bạn cũng nhận được kết quả tương tự và bạn vẫn gặp sự cố này. Đó là bởi vì theo truyền thống, không có những thứ như đối tượng Date
trong .Net. Vì vậy, bất kể bạn có được giá trị như thế nào, một khi bạn loại bỏ thời gian - bạn phải nhớ rằng nó không thực sự đại diện cho "nửa đêm", mặc dù đó là giá trị bạn đang làm việc.
Nếu bạn thực sự muốn có giải pháp hoàn toàn chính xác cho vấn đề này, cách tiếp cận tốt nhất là sử dụng NodaTime. Lớp LocalDate
thể hiện đúng ngày không có thời gian. Bạn có thể lấy ngày hiện tại cho bất kỳ múi giờ nào, bao gồm múi giờ hệ thống địa phương:
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;
Nếu bạn không muốn sử dụng Giờ Noda, bây giờ có một tùy chọn khác. Tôi đã đóng góp việc triển khai đối tượng chỉ có ngày vào dự án .Net CoreFX Lab. Bạn có thể tìm đối tượng gói System.Time
trong nguồn cấp dữ liệu MyGet của họ. Khi bổ sung vào dự án của bạn, bạn sẽ tìm thấy bạn có thể làm bất cứ điều nào sau đây:
using System;
...
Date localDate = Date.Today;
Date utcDate = Date.UtcToday;
Date tzSpecificDate = Date.TodayInTimeZone(anyTimeZoneInfoObject);
Thời gian. .Now
bao gồm các 09:23:12 hoặc bất cứ điều gì; .Today
chỉ là ngày tháng (vào lúc 00:00:00 vào ngày đó).
Vì vậy, hãy sử dụng .Now
nếu bạn muốn bao gồm thời gian và .Today
nếu bạn chỉ muốn ngày!
.Today
là cơ bản giống như .Now.Date
...và sử dụng 'UtcNow' trừ khi bạn * thực sự * muốn múi giờ địa phương của hệ thống. (Cụ thể, trên một ứng dụng web hầu như luôn là lựa chọn sai.) –
DateTime.Today đại diện cho ngày hệ thống hiện tại với phần thiết lập thời gian để 00:00:00
và
DateTime.Now đại diện cho ngày hệ thống hiện tại và thời gian
chỉ là một quan sát ... tài liệu 1.1 ít chi tiết hơn 4.0 tài liệu; nó có lẽ tốt hơn để liên kết với vLatest? –
quyền của bạn tôi đã thay đổi các liên kết –
@megaperlz: Bạn hiện đang liên kết tới 4.0 thay vì vLatest. Các liên kết VLatest có thể được thực hiện bằng cách xóa '(v = VS.100)'. – Brian
Thuộc tính DateTime.Now
trả về ngày và giờ hiện tại, ví dụ 2011-07-01 10:09.45310
.
Thuộc tính DateTime.Today
trả về ngày hiện tại với thời gian được đặt thành 0, ví dụ 2011-07-01 00:00.00000
.
Thuộc tính DateTime.Today
thực sự được thực hiện để trở DateTime.Now.Date
:
public static DateTime Today {
get {
DateTime now = DateTime.Now;
return now.Date;
}
}
ví dụ rất đơn giản với sự khác biệt rõ ràng – Cherry
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
tôi nghĩ thêm những liên kết này -
- 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 bao gồm các DateTime, DateTimeOffset và TimeZoneInfo loại, tất cả đều có thể được sử dụng để xây dựng các ứng dụng làm việc với ngày tháng và thời gian.
- Performing Arithmetic Operations with Dates and Times-MSDN
Trở lại câu hỏi ban đầu, Sử dụng Reflector tôi đã giải thích sự khác biệt trong mã
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);
}
}
DateTime.Today
là DateTime.Now
với thời gian thiết lập để không. Điều quan trọng cần lưu ý là có sự khác biệt giữa giá trị DateTime, biểu thị số lượng ve đã trôi qua kể từ nửa đêm ngày 1 tháng 1, 0000 và biểu thị chuỗi giá trị DateTime đó, biểu thị ngày tháng và giá trị thời gian trong một định dạng văn hóa đặc trưng cụ thể: https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx
DateTime.Now.Ticks
là thời gian thực tế lưu trữ bởi .net (thực chất là thời gian UTC), phần còn lại chỉ là cơ quan đại diện (mà rất quan trọng cho mục đích hiển thị).
Nếu thuộc tính Kind
là DateTimeKind.Local
nó ngầm định bao gồm thông tin múi giờ của máy tính cục bộ. Khi gửi qua dịch vụ web .net, giá trị Ngày giờ theo mặc định được tuần tự hóa với thông tin múi giờ được bao gồm, ví dụ: 2008-10-31T15: 07: 38.6875000-05: 00 và máy tính ở múi giờ khác vẫn có thể biết chính xác thời gian được giới thiệu.
Vì vậy, việc sử dụng DateTime.Now và DateTime.Today hoàn toàn OK.
Bạn thường bắt đầu gặp sự cố khi bạn bắt đầu nhầm lẫn biểu diễn chuỗi với giá trị thực và cố gắng "sửa" DateTime, khi nó không bị hỏng.
- 1. Sự khác nhau giữa .Equals và ==
- 2. Sự khác nhau giữa% w và% W
- 3. Sự khác nhau giữa ParameterInfo.DefaultValue và ParameterInfo.RawDefaultValue
- 4. Sự khác nhau giữa MBean và MXBean
- 5. Sự khác nhau giữa ConfigurationManager và ConfigurationSettings
- 6. Sự khác nhau giữa Tkinter và Tkinter
- 7. Sự khác nhau giữa! = Và =! trong Java?
- 8. Sự khác nhau giữa 'SpecialFolder.LocalApplicationData' và 'SpecialFolder.ApplicationData'?
- 9. Sự khác nhau giữa String.getBytes() và IOUtils.toByteArray()?
- 10. Sự khác nhau giữa presentModalViewController và presentViewController?
- 11. Sự khác nhau giữa NSInvocationOperation và NSBlockOperation
- 12. Sự khác nhau giữa TVar và TMVar
- 13. Sự khác nhau giữa onClickListener và onItemClickListener
- 14. Sự khác nhau giữa `require` và` gem`
- 15. Sự khác nhau giữa HttpUtility.HtmlEncode và Server.HtmlEncode
- 16. Sự khác nhau giữa sqlplus và sqldeveloper?
- 17. Sự khác nhau giữa JPA và JPA2
- 18. Sự khác nhau giữa DECIMAL và NUMERIC
- 19. Sự khác nhau giữa "./somescript.sh" và ". ./somescript.sh"
- 20. Sự khác nhau giữa GIT và CVS
- 21. Sự khác nhau giữa System.Drawing.Point và System.Drawing.PointF
- 22. Sự khác nhau giữa REST và WebServices
- 23. Sự khác nhau giữa sys và os.sys
- 24. Sự khác nhau giữa select() và selectAll()
- 25. Sự khác nhau giữa restartLoader và onContentChanged
- 26. Sự khác nhau giữa dbcontext.Add và dbcontext.AddObject
- 27. Sự khác nhau giữa int32_t và int_fast32_t
- 28. Sự khác nhau giữa | và || trong MATLAB?
- 29. Có sự khác nhau giữa "và"
- 30. Sự khác nhau giữa `% trong%` và `== '
Điều gì về việc sử dụng 'DateTime.UtcNow' thay vì' DateTimeOffset.Now'? –
'DateTime.UtcNow' là có thể chấp nhận được nếu bạn có thể truyền đạt trong ứng dụng của bạn hoặc chỉ ra rằng giá trị là UTC. (Tôi thích thực sự gọi trường hoặc thuộc tính giống như 'MyDateUtc' thay vì chỉ' MyDate' - nhưng đó chỉ là đóng băng trên bánh.) Nếu bạn không thể truyền đạt nó trong tên spec hoặc field, thì 'DateTimeOffset.UtcNow 'có thể được sử dụng để đảm bảo bù trừ zero được chuyển tải với các giá trị ngày tháng và thời gian. –
Chúng không bằng nhau. Hôm nay có thời gian là 00:00:00. –