I need to update this FAQ: http://www.gotdotnet.com/team/clr/bcl/TechArticles/techarticles/datetimefaq.doc
However before I get around to do it, I want to re-post it as is. If you are doing anything with DateTime, you should really read this.
.NET Framework Date and Time FAQ
Authors: Anthony Moore, Kit George, Katy King
Updated: November 06 2003
Applies: .NET Framework V1.0 and V1.1 and “Whidbey” pre-release
Frequently asked questions about date and time related classes, including System.DateTime, System.TimeSpan and System.TimeZone.
There are some very common misunderstandings with the DateTIme class.
The first about what DateTime behavior is affected by the current culture, because most methods on DateTime used a fixed Gregorian calendar, but some key off the calendar data in the current culture on the thread.
The second is about the time zone that a DateTime instance represents. The DateTime class does not represent a specific time zone at all, but rather specific methods will assume input is in local time or UTC, and will return output in one format or another.
Most of the behavior of the DateTime class is not based on the current culture, and is based around a standard Gregorian calendar with 1AD as the base year. However, a small set of the methods, most notably DateTime.Parse and DateTime.ToString, do vary behavior based on the culture.
In version 1.0 and 1.1 of the framework, the following methods have behavior that changes with the current culture:
All other members, including the Year, Month and Day properties and methods like AddMonths, do not having varying behavior and are based on a Gregorian calendar with 1AD as the base year.
The constructors that take a Calendar instance are a special case. These constructors cause the other parameters to be passed in to be interpreted according to the Calendar passed in, but this is still independent of the current culture on the thread.
If you need members like Year, Month, Day or AddMonths to behave based on the current culture, you need to access the Calendar instance on the DateTimeFormatInfo instance for the current culture. For example, to add months:
Calendar cal = CultureInfo.CurrentCulture.DateTimeFormat.Calendar
date = cal.AddMonths(date, 1);
To make operations like DateTime.Parse and DateTime.ToString not change behavior based on the current culture, pass in the InvariantCulture instance like so:
A common misconception about DateTime is that it represents a local time, or can represent a universal time by switching to a distinct different mode. In fact the DateTime is neither local nor universal. It can represent either of those or it can be used in a more abstract sense, but here is no information in the DateTime instance that has anything to do with the Time Zone. A good analogy is the Decimal class. You can use it to represent a currency, but which currency it is depends on the context of the application.
What does get stored in the DateTime class is just a big number that can represent a time like “5 Sep 2003, 4:17:00 pm”. However, that same time in local or universal or Sydney time has exactly the same representation.
That being said, there are various operations on DateTime that really require a time zone to work correctly. A good example of this DateTime.ToUniversalTime, which needs to make an assumption about what the time zone of the input is. In this case, it assumes it is local
Similarly, there are operations that return DateTime instances that are clearly associated with either local or universal times.
The majority of methods on DateTime are completely independent of the concept of a time zone. This includes all the constructors, properties like Year, Month and Day, and methods like AddMonths and AddHours.
The following methods on the DateTime and TimeZone classes assume that their input is in local time:
The following methods return a local time:
The following methods assume that their input is in UTC:
The following methods return a UTC time:
Throughout the rest of the framework, almost all DateTime instances are either local times (e.g. System.IO.FileInfo.LastAccessTime), or the time zone does not matter (such as the dates in the System.Web.UI.Controls.Calendar control). A small number take or return UTC, but these will be post-fixed with “Utc”, (e.g. System.IO.FileInfo.LastAccessTimeUtc in V1.1 only).
ToString, Parse and ParseExact have a more complex relationship with the time zone. Most of the time their operations are independent of the time zone, but certain date and time formats do interact with it.
Beware: because the DateTime is time zone agnostic, these methods cannot detect if you pass in a Local instance to a method that assumes UTC or vice versa.
Not in V1.0, V1.1 or the “Whidbey” pre-release.
The .NET Framework does support conversion to and from UTC and the system’s current local time. It can also support parsing a DateTime from an arbitrary time zone offset, such as “2003-10-26T13:11:07+10:00”, but it must always convert this either to Local or UTC.
This is a very common feature request and is likely to be in a future version.
People are often surprised why this feature cannot be supplied by Microsoft at low cost. In particular, data to do conversions exists in the Windows registry and is used by the time zone selection dialog. However, there is a big distinction between having UI and registry data and having an API.
This is a more expensive feature to undertake for Microsoft than most people would imagine because (a) an API must provide consistent behavior from one machine to another so we can’t just re-expose the registry data and (b) there is cost for Microsoft in exposing an official Time Zone conversion because we face on-going geo-political costs for any country/region based data we gather and maintain. For example, a country may threaten to boycott our product if they are not listed in the data. This has happened to us with our CultureInfo data on many occasions, and we often need to tweak data in service packs, which is expensive and risky.
That being said, there is agreement that this is a very important feature, and it is under serious consideration for the WinFx release.