DateTimeOffset parse and custom time zone - c#

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));
}

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.

DateTime format usage in C#

I have following date time format
TimeZoneDetails.TimeZoneInstance ="Australia/Perth"
DateTime Today = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow,TimeZoneDetails.TimeZoneInstance);
Does today variable store the date based on timezone?
string date = "2020-03-19";
DateTime startdate = DateTime.Parse(date);
What is the timezone of startdate variable?
DateTime enddate = TimeZoneInfo.ConvertTimeToUtc(startdate, TimeZoneDetails.TimeZoneInstance);
Will enddate variable converted to UTC time?
A few things:
"Australia/Perth" is an IANA time zone identifier. It will work with .NET on Linux or Mac OSX, but on Windows you'd have to use "W. Australia Standard Time" instead. Alternatively, you could use my TimeZoneConverter library to work with either form of identifier on any platform.
In your code:
TimeZoneDetails.TimeZoneInstance ="Australia/Perth"
This isn't generally valid. Given the usage in the rest of your code, your TimeZoneInstance would have to be a TimeZoneInfo object. You can't assign a string in that way. You'd have to use a function like TimeZoneInfo.FindSystemTimeZoneById, or TZConvert.GetTimeZoneInfo from TimeZoneConverter, or a similar function in your own code. (Also you're missing a semicolon.)
In your code:
string date = "2020-03-19";
DateTime startdate = DateTime.Parse(date);
You asked what the time zone is in the startdate variable. That's a DateTime, which does not store time zone or offset information. It only has a .Kind property, which is of type DateTimeKind. In your example, it will be DateTimeKind.Unspecified. Also note the time will be set to 00:00:00.0000000.
You can read more about this in the documentation, here and here.
In your code:
DateTime enddate = TimeZoneInfo.ConvertTimeToUtc(startdate, TimeZoneDetails.TimeZoneInstance);
Yes, that will correctly convert the DateTime from the time zone given to UTC. Because startdate.Kind == DateTimeKind.Unspecified, the value is treated as belonging to the time zone specified. The resulting value will have enddate.Kind == DateTimeKind.Utc.
You can read more in the documentation, here.
In comments you asked:
which one is default for DateTimeKind?
That depends on which method you call to create the DateTime, and what values you pass in. In your case, because you call DateTime.Parse and pass a string that contains no time zone offset information, the resulting value has .Kind == DateTimeKind.Unspecified. You can read more about the behavior of DateTime.Parse in the remarks section here. Other methods and constructors behave similarly, but you should check the documentation for each, or validate the results yourself. You may find conversion errors if you, for example, think a DateTime has Unspecified kind, but it actually has Local kind due to how you obtain it.

How to convert string offset to timespan in c#

I'm trying to convert the convert time to the user's time zone, but I don't have the windows time zone string such as "Pacific Standard Time". All I have is a string offset such as "-07:00". Looks like I need to create a timespan. Is the only way to parse this string manually?. Seems like there should be a way to convert a time using a string offset, but maybe I am missing something.
I have this but it requires the timezone. I'm trying to modify it to use the offset instead, but you can see the timespan that is created for the conversion and I need to get my offset to the timespan.
static void Main(string[] args)
{
var currentTimeInPacificTime = ConvertUtcTimeToTimeZone(DateTime.UtcNow, "Pacific Standard Time");
//TimeSpan ts = new TimeSpan("-07:00");
Console.ReadKey();
}
static DateTimeOffset ConvertUtcTimeToTimeZone(DateTime dateTime, string toTimeZoneDesc)
{
if (dateTime.Kind != DateTimeKind.Utc) throw new Exception("dateTime needs to have Kind property set to Utc");
TimeSpan toUtcOffset = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc).GetUtcOffset(dateTime);
var convertedTime = DateTime.SpecifyKind(dateTime.Add(toUtcOffset), DateTimeKind.Unspecified);
return new DateTimeOffset(convertedTime, toUtcOffset);
}
You can just use the TimeSpan.Parse method:
TimeSpan ts = TimeSpan.Parse("-07:00");
Console.WriteLine(ts); // -07:00:00
Be careful to strip a leading "+" as TimeSpan.Parse will fail here. "+01:00" is incorrect, but "01:00" works.
Or if you want be a little more safe, try the TimeSpan.TryParse method:
TimeSpan ts;
if (TimeSpan.TryParse("-07:00", out ts))
Console.WriteLine(ts); // -07:00:00
But of course if all you want to do is convert a UTC date/time to a local date/time, you can just do this:
DateTime localDateTime = utcDateTime.ToLocalTime();
Or to convert it to any timezone:
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc);
DateTime localDateTime = TimeZoneInfo.ConvertTime(utcDateTime, tzi);
For more complicated/non-standard formats you can also use TimeSpan.ParseExact(String, String, IFormatProvider), where the second String is a Custom TimeSpan Format String.
API information is available at msdn.microsoft.com, and is linked above.linked.
I'm trying to convert the convert time to the user's time zone, but I don't have the windows time zone string such as "Pacific Standard Time". All I have is a string offset such as "-07:00".
Then you don't have what you need to make the correct conversion. Read "Time Zone != Offset" in the timezone tag wiki.
It is important to understand that the "Pacific Standard Time" value is the .Id for the TimeZoneInfo object that is used for US Pacific Time. It covers both Pacific Standard Time (UTC-8) and Pacfic Daylight Time (UTC-7).
All I have is a string offset such as "-07:00". Looks like I need to create a timespan.
Now you have what is commonly called the XY Problem. You shouldn't have any need to work with the offset by itself.
In your code, there is a call to dateTime.Add(toUtcOffset). When doing time zone conversions, this is a code smell that you are doing it wrong. You should never have to manually add or subtract time just to manipulate time zones. That should be reserved for actually changing the moment in time you are talking about.
What you should be doing is to collect a real time zone id from your user. Either "Pacific Standard Time" for use with TimeZoneInfo, or "America/Los_Angeles" for use with a TZDB implementation like Noda Time.
If time zone conversions aren't important in your context, then you might just want to collect a full DateTimeOffset value such as 2013-08-17T13:27:00.000-07:00 instead.
There are time zone strings which includes "Pacific Standard Time". The complete list can be found here. http://www.xiirus.net/articles/article-_net-convert-datetime-from-one-timezone-to-another-7e44y.aspx
Any DateTime object can be converted to some timezone -
TimeZoneInfo timeZoneInfo;
DateTime dateTime ;
//Set the time zone information to Pacific Standard Time
timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
//Get date and time in US Mountain Standard Time
dateTime = TimeZoneInfo.ConvertTime(DateTime.Now, timeZoneInfo);
//Print out the date and time
Console.WriteLine(dateTime.ToString("yyyy-MM-dd HH-mm-ss"));
So you method can be modified as -
static DateTimeOffset ConvertUtcTimeToTimeZone(DateTime dateTime, string toTimeZoneDesc)
{
return new DateTimeOffset(TimeZoneInfo.ConvertTime(dateTime, TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc)));
}

Parsing DateTime with a known but not given time zone

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.

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