Posted By: Anonymous
Can anyone explain the difference between
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.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:
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
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
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
// 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);