Parsing DateTime with a known but not given time zone - c#

I'm stuck with a problem around parsing date and time:
I'm trying to parse a datetime string extracted from a german website. It is given in the format 'day.month.year 24hours:minutes', like:
01.01.2011 17:00
And it is always in the german timezone. But here comes the problem:
'01.01.2011 17:00' should be parsed to a DateTime struct with '01.01.2011 16:00' in UTC (here, the timezone is CET, without daylight saving time)
while '01.06.2011 17:00' should be parsed to a DateTime struct with '01.01.2011 15:00' in UTC (here, the timezone is CEST, with daylight saving time)
I have no clue how to achieve this. If I set my local clock to the german timezone, and I parse with DateTime.ParseExact and the flag DateTimeStyles.AssumeLocal and DateTimeStyles.AdjustToUniversal it is parsed correctly. However, I want any client to parse it independently from their local clock and timezone. Also, I dont want to do the timezone offset myself, because it depends on the date (summer: -2 / winter: -1).
Once I have the datetime in UTC it would be easy to convert it to any local timezone.

It sounds like you know what time zone you should be parsing it with. Assuming .NET 3.5 (and thus TimeZoneInfo) you should logically:
Parse it as a "local" time (not time zone specific)
Convert that local time to a UTC time
Unfortunately DateTime makes that slightly tricky. EDIT: I thought you'd want to convert parse it using DateTimeStyles.AssumeUniversal - but that ends up returning a local DateTime, annoyingly. Basically you want to end up with a DateTime with the right time so that you can use:
parsed = DateTime.SpecifyKind(parsed, DateTimeKind.Unspecified);
You can then get a UTC value with:
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(parsed, germanTimeZone);
Note that you really want an "unspecified" date time first, so that you can convert it to UTC in an arbitrary time zone. You should also remember the possibility that a local time is ambiguous (occurs twice) or impossible (doesn't occur at all) due to DST changes.
And yes, this will be a lot easier in Noda Time when it's finished :)

After having seen that the task can not be archieved with the help of the WP7/Silverlight framework, I wrote a small helper that does the job:
public static class DateTimeHelper
{
/// <summary>
/// Tries to parse the given datetime string that is not annotated with a timezone
/// information but known to be in the CET/CEST zone and returns a DateTime struct
/// in UTC (so it can be converted to the devices local time). If it could not be
/// parsed, result contains the current date/time in UTC.
/// </summary>
public static bool TryParseCetCest(string s, string format, IFormatProvider provider, DateTimeStyles style, out DateTime result)
{
// Parse datetime, knowing it is in CET/CEST timezone. Parse as universal as we fix it afterwards
if (!DateTime.TryParseExact(s, format, provider, style, out result))
{
result = DateTime.UtcNow;
return false;
}
result = DateTime.SpecifyKind(result, DateTimeKind.Utc);
// The boundaries of the daylight saving time period in CET and CEST (_not_ in UTC!)
// Both DateTime structs are of kind 'Utc', to be able to compare them with the parsing result
DateTime DstStart = LastSundayOf(result.Year, 3).AddHours(2);
DateTime DstEnd = LastSundayOf(result.Year, 10).AddHours(3);
// Are we inside the daylight saving time period?
if (DstStart.CompareTo(result) <= 0 && result.CompareTo(DstEnd) < 0)
result = result.AddHours(-2); // CEST = UTC+2h
else
result = result.AddHours(-1); // CET = UTC+1h
return true;
}
/// <summary>
/// Returns the last sunday of the given month and year in UTC
/// </summary>
private static DateTime LastSundayOf(int year, int month)
{
DateTime firstOfNextMonth = new DateTime(year, month + 1, 1, 0, 0, 0, DateTimeKind.Utc);
return firstOfNextMonth.AddDays(firstOfNextMonth.DayOfWeek == DayOfWeek.Sunday ? -7 :
(-1 * (int)firstOfNextMonth.DayOfWeek));
}
}
The trick was to parse it without the DateTimeStyles.AssumeUniversal flag (this makes TryParseExact assume the date is UTC and returning the date converted/adjusted to local), respecifying it as UTC and then manually adjusting it to the actual UTC equivalent.
It follows the DST rules that can be found here. I tested it with all 4 boundary cases just before/after the start/end of the daylight saving time. That showed again the importance of testing: I had to change the < operator in DstStart.CompareTo(result) < 0 to <= to make it produce the correct result.
I had the feeling that I am reinventing the wheel here (which I hate to do), but did not want to use a dedicated library for this simple job. I had a look at Noda Time which is a great project, but I think its not necessary for this.
I hope I can save someone a little time with this small helper. It is intentionally not generic for all time zones (if you need this use a lib like Noda Time instead), but for these cases in which you just have one fixed single time zone, like in my case.

Related

How to parse time into DateTimeOffset in a specific time zone?

Given the 11:00 PM, and knowing that the server is running using UTC time, I need to take that time parse it into a DateTimeOffset from a specific TimeZone.
For example if the docker container's time running the server is 2:00 AM 6/3/2022, I need to be able to check if current date time now in 'Eastern Standard Time' zone, is past 6/2/2022 11:00 PM or before.
To get localized DateTime now I have the following code which works as expected:
TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
DateTime nowLocalTime = TimeZoneInfo.ConvertTime(DateTime.Now, tzInfo);
DateTimeOffset targetDateTimeOffset =
new DateTimeOffset(nowLocalTime,
tzInfo.GetUtcOffset
(
DateTime.SpecifyKind(nowLocalTime, DateTimeKind.Local)
));
I thought I had it figured out for parsing the time into DateTime and then getting the specific DateTimeOffset object, until it hit past midnight on the server. Since the server's time is now 12:01 AM 6/3/2022 when I run the following code:
string timeOfDay = "11:00 AM";
TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
DateTime.TryParse(timeOfDay, out DateTime dateTime);
DateTimeOffset targetDateTimeOffset =
new DateTimeOffset
(
dateTime,
tzInfo.GetUtcOffset
(
DateTime.SpecifyKind(dateTime,
DateTimeKind.Local)
)
);
This now returns 6/3/2022 11:00PM. This makes sense but I need to get DateTimeOffset parsed into the specified TimeZone. Because right now in 'Eastern Standard Time' zone it is 6/2/2022 not 6/3/2022. So basically I need to take 11:00 PM parse it into DateTimeOffset of the provided TimeZone, is that possible?
The .net DateTime type was designed before the age of cloud computing. Where you only had to worry about the machine's .Local time or .Utc. IMHO DateTimeKind.Unspecified should be marked [Obsolete] and any API behaviour which relies on it should instead throw an exception.
TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo) is a particularly strange function. If you pass a DateTimeKind.Unspecified, or a TimeZoneInfo other than TimeZoneInfo.Local or TimeZoneInfo.Utc, the result is essentially unusable.
IMHO you're better off pushing the problem of parsing and displaying date / time values to the client. Force the client to parse any date time strings in their local timezone. Then either use UTC everywhere, or use DateTimeOffset to store the timezone explicitly.
It's easy enough to get the current time in a specific timezone;
TimeZoneInfo tzInfo = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
DateTimeOffset tzLocalTime = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzInfo);
Unfortunately while you can parse a string and .AssumeLocal or .AssumeUniversal, anything else is barely supported or documented. While you can provide a CultureInfo for parsing non-gregorian calendars, there's no DateTimeOffset.Parse which takes a default TimeZoneInfo parameter. The closest I've found is to check if the string contains an offset, based on this question.
static DateTimeOffset ParseAsDateTimeOffset(string s, TimeZoneInfo defaultTimeZone, CultureInfo culture = null)
{
if (Regex.IsMatch(s, #"(Z|[+-]\d{2}:\d{2})$"))
return DateTimeOffset.Parse(s, culture ?? CultureInfo.InvariantCulture);
var dt = DateTime.Parse(s, culture ?? CultureInfo.InvariantCulture);
return new DateTimeOffset(dt, defaultTimeZone.GetUtcOffset(dt));
}
While this works for most of the year, I'm not certain if it works properly for time values around DST adjustments. But without an explicit offset, those values are going to be wrong anyway.

Get time zone with UTC conversion

I have the system date in BST . I want to convert it to UTC. So did the below:
string utcDate= TimeZoneInfo.ConvertTimeToUtc(dt).ToString("dd/MM/yyyy HH:mm:ss");
What I want is to get the zone along with the Date in UTC. Pls consider the daylight savings.
Example: 2019-07-08T23:59:00+01:00.
A few things:
The string format you gave the example of, 2019-07-08T23:59:00+01:00 is part of the ISO 8601 specification. To be precise, it is the "complete date and time of day representation" of the "ISO 8601 Extended Format". It also the format defined by RFC 3339.
In this format, the date and time portion represent the local time, as denoted by the time zone offset portion. In other words, the values are not in UTC, but already adjusted. In your example, 2019-07-08T23:59:00 is the local time and UTC+01:00 is in effect at that time. The corresponding UTC time would thus be an hour earlier, 2019-07-08T22:59:00Z.
You seem to be asking for the date in UTC but with an offset that includes daylight saving time. That is impossible, as UTC does not observe daylight saving time. The offset from UTC is always zero. You can read more about UTC here.
The offset of UTC itself is denoted with Z, but can also be represented with +00:00, which can be thought of as "zero offset from UTC". In other words, if you are referring to UTC time use the Z, and if you are referring to a local time that is aligned to UTC (such as GMT in London in the winter, or Iceland, etc.) use +00:00.
In your question, you say you want the system time in UTC with the offset. I will assume by "system time" you mean the current time of the clock on the system. That is provided by DateTime.UtcNow or DateTimeOffset.UtcNow. These return either a DateTime or DateTimeOffset structure - not a string. Since you wanted a string in a specific format, then you should first ask for the current time, and then format it as a string with ToString:
using System.Globalization;
...
string a = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T22:59:00Z"
string b = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T22:59:00+00:00"
If what you actually wanted was the local time, such that the offset would be +00:00 in the winter and +01:00 in the summer (in the UK), then use Now instead of UtcNow. This gives the local time in the time zone of the computer where the code is running.
string c = DateTime.Now.ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
string d = DateTimeOffset.Now.ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
If you actually wanted the time in the UK regardless of what the time zone of the local computer was on, then you'd have to first get the UTC time and then convert it to UK time before creating the string.
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
string e = TimeZoneInfo.ConvertTime(DateTime.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:ssK", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00"
string f = TimeZoneInfo.ConvertTime(DateTimeOffset.UtcNow, tzi).ToString("yyyy-MM-dd'T'HH:mm:sszzz", CultureInfo.InvariantCulture);
// output example: "2019-07-08T23:59:00+01:00"
In example e, note that a DateTime can't store an arbitrary offset as the result of time zone conversion, and thus you get DateTimeKind.Unspecified assigned to the Kind property, which results in no offset being in the string representation. Thus most of the time you should use a DateTimeOffset (example f) instead.
Also, note the time zone ID of "GMT Standard Time" is the correct ID to use for the UK on Windows platforms. It correctly switches between GMT and BST when appropriate. If you are running .NET Core on non-Windows platforms (Linux, OSX, etc.), then you should use "Europe/London" instead. Or if you are wanting to write code that is platform-neutral then you can use my TimeZoneConverter library, which allows you to provide either form and run on any platform.
In your code example, you didn't call any of the "now" functions, but gave a dt variable. Assuming this is a DateTime, the result of calling TimeZoneInfo.ConvertTimeToUtc will depend on the Kind property of that variable. If it's DateTimeKind.Utc, then no conversion is performed. If it's DateTimeKind.Local or DateTimeKind.Unspecified, then the value is converted from the computer's local time zone to UTC.
Lastly, keep in mind that when talking to an international audience, time zone abbreviations can be ambiguous. I could deduce by "BST" that you meant British Summer Time, but only because you showed a +01:00 offset in your question. "BST" can also stand for "Bangladesh Standard Time" (+06:00), or "Bougainville Standard Time" (+11:00).
I guess you can do something like this:
var dt = DateTime.Now;
string utcDate = dt.ToUniversalTime().ToString("dd/MM/yyyy HH:mm:ss") +
dt.ToString(" zzz");
Output: (I'm in EET)
14/07/2019 20:02:17 +02:00
But be aware that this could be confusing to people. The standard way is that the timezone follows the local date, not the universal date.

DateTimeOffset parse and custom time zone

We are parsing XML DateTime values into a DateTimeOffset value. According to the W3C XSD documentation for DateTime, the type may have a timezone info or not.
Our requirment says:
If time zone info is provided in XML, use this time zone
If no time zone info is provided, assume it's a local time in a predefined, configurable time zone (not the one from Server).
The Problem is that when a XML DateTime without a time zone is parsed into a DateTimeOffset, it uses the local (System) timezone by default. It seems not possible to override the default timezone and also not possible to identify wheter the timezone was parsed or added internally.
Is there any way I can specify the default timezone used by the DateTimeOffset parsing?
If not, how can one identify if the time zone was parsed or added automatically during parsing for DateTimeOffset?
It seems strange to me that there is no support to set the time zone for a .NET application the same way as one can set the current culture.
Therefore the only approach to this problem seems to first parse the value into DateTime and check the Kind property. If Kind is not Unspecified, parse the value again into a DateTimeOffset:
/*
sample values:
- 2015-06-03T10:47:01
- 2015-06-03T07:47:01Z
- 2015-06-03T10:47:01+03:00
*/
DateTimeOffset dto;
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["DefaultTimeZone"]);
var dt = DateTime.Parse(value);
if (dt.Kind == DateTimeKind.Unspecified)
{
dto = new DateTimeOffset(dt, timeZone.GetUtcOffset(dt));
}
else
{
dto = DateTimeOffset.Parse(value);
}
The simplest way would be to test the string ahead of time to see if it contains an offset. Regular expressions work well for this.
Here is a function that should work well for the case you described:
static DateTimeOffset ParseAsDateTimeOffset(string s, TimeSpan defaultOffset)
{
if (Regex.IsMatch(s, #"(Z|[+-]\d{2}:\d{2})$"))
return DateTimeOffset.Parse(s, CultureInfo.InvariantCulture);
var dt = DateTime.Parse(s, CultureInfo.InvariantCulture);
return new DateTimeOffset(dt, defaultOffset);
}
You might also consider a slight variation of that, which is to provide a default time zone, rather than a default offset. This is an important distinction, since the offset of a time zone can change depending on whether the specific date is in a daylight saving time period or not. See also "Time Zone != Offset" in the timezone tag wiki.
static DateTimeOffset ParseAsDateTimeOffset(string s, TimeZoneInfo defaultTimeZone)
{
if (Regex.IsMatch(s, #"(Z|[+-]\d{2}:\d{2})$"))
return DateTimeOffset.Parse(s, CultureInfo.InvariantCulture);
var dt = DateTime.Parse(s, CultureInfo.InvariantCulture);
return new DateTimeOffset(dt, defaultTimeZone.GetUtcOffset(dt));
}

.NET DateTime & TimezoneInfo.ConvertTime party

The thing I want to do is quite simple:
private static TimeZoneInfo Tzi = // ... custom timeZone I've set;
public static DateTime ToTimeZone(DateTime dateTime, TimeZoneInfo target)
{
return TimeZoneInfo.ConvertTime(dateTime, Tzi, target);
}
Idea is - all dates that come to the server are automatically converted to certain TimeZone and saved like that to DB (UTC, Central US, Pacific US, whatever).
And this works quite well as long as timezone set on the server is same as Tzi. However, when that's not true, conversion fails - when creating DateTime instance .NET sets it to TimeZone of the machine and then TimeZoneInfo.ConvertTime(dateTime, Tzi, target) processes my request in a funky way. For example, let's say that Server TimeZone is Pacific (UTC -8), I set Tzi to Central (UTC -6), and I target Singapure (UTC +8).
Now when I call TimeZoneInfo.ConvertTime(dateTime, Tzi, target) first "converts" dateTime from UTC -8 to UTC -6 (Tzi time zone), adding 2 hours... and only then from Tzi to target.
Is there a way to signal to TimeZoneInfo.ConvertTime that dateTime I am sending is in TimeZone I am passing in as from parameter, and not in the TimeZone of server?
EDIT:
OK, both answers are great recommendations, but it seems I have different kind of trouble. TimeZoneInfo.ConvertTime(dateTime, Tzi, target) seems to be working correctly, and the real culprit is actually:
return Json(new {data}, JsonRequestBehavior.AllowGet);
that outputs dates like: "Created":"/Date(1346810072950)/". I've confirmed that sent date is different depending on TimeZone on the server (AppPool restart is needed after changing server's TimeZone). Anyone have experience with this and suggestion on how to influence the way ASP.NET MVC outputs dates in JSON that's sent back to client?
ConvertTime should do the job. Maybe your issue is the DateTime.Kind.
See the following example:
// Gets current local date
// Returns 04/09/12 11:30 in my case
var date = DateTime.Now;
// Sets DateTime as Unspecified kind (not local nor UTC)
// Returns same date as before, but the date is not tagged as "local"
date = DateTime.SpecifyKind(date, DateTimeKind.Unspecified);
// Converts the current date, specified as UTC+12, into a date specified as UTC-11
// Returns 03/09/12 12:30 in my case, which is the expected result
// (23 hours between previous date and result)
var zz = TimeZoneInfo.ConvertTime(
date,
TimeZoneInfo.FindSystemTimeZoneById("UTC+12"),
TimeZoneInfo.FindSystemTimeZoneById("UTC-11"));
You can use DateTimeOffset instead of DateTime - this structure includes a timezone offset property, so when creating instances of it you should specify what offset to use.

Difference between System.DateTime.Now and System.DateTime.Today

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);
Time. .Now includes the 09:23:12 or whatever; .Today is the date-part only (at 00:00:00 on that day).
So use .Now if you want to include the time, and .Today if you just want the date!
.Today is essentially the same as .Now.Date
The DateTime.Now property returns the current date and time, for example 2011-07-01 10:09.45310.
The DateTime.Today property returns the current date with the time compnents set to zero, for example 2011-07-01 00:00.00000.
The DateTime.Today property actually is implemented to return DateTime.Now.Date:
public static DateTime Today {
get {
DateTime now = DateTime.Now;
return now.Date;
}
}
DateTime.Today represents the current system date with the time part set to 00:00:00
and
DateTime.Now represents the current system date and time
I thought of Adding these links -
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
The .NET Framework includes the DateTime, DateTimeOffset, and
TimeZoneInfo types, all of which can be used to build applications
that work with dates and times.
Performing Arithmetic Operations with Dates and Times-MSDN
Coming back to original question , Using Reflector i have explained the difference in code
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 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
DateTime.Today is DateTime.Now with time set to zero.
It is important to note that there is a difference between a DateTime value, which represents the number of ticks that have elapsed since midnight of January 1, 0000, and the string representation of that DateTime value, which expresses a date and time value in a culture-specific-specific format:
https://msdn.microsoft.com/en-us/library/system.datetime.now%28v=vs.110%29.aspx
DateTime.Now.Ticks is the actual time stored by .net (essentially UTC time), the rest are just representations (which are important for display purposes).
If the Kind property is DateTimeKind.Local it implicitly includes the time zone information of the local computer. When sending over a .net web service, DateTime values are by default serialized with time zone information included, e.g. 2008-10-31T15:07:38.6875000-05:00, and a computer in another time zone can still exactly know what time is being referred to.
So, using DateTime.Now and DateTime.Today is perfectly OK.
You usually start running into trouble when you begin confusing the string representation with the actual value and try to "fix" the DateTime, when it isn't broken.
DateTime.Now.ToShortDateString() will display only the date part

Categories