The DateTime value type represents dates and times with values ranging from 00:00:00.0, January 1, 1601 Anno Domini, or A.D. (also known as Common Era, or C.E.) through 11:59:59 P.M., December 31, 9999 A.D. (C.E.) These limits are stored as read-only values in the MinValue and MaxValue fields.
Time values are measured in 100-nanosecond units called ticks, and a particular date is expressed as the number of ticks that have elapsed since 12:00 midnight, January 1, 1601 A.D. (C.E.) in the Gregorian calendar. For example, a tick value of 31241376000000000L represents Friday, January 01, 0100 12:00:00 midnight.
Descriptions of time values in the DateTime type are often expressed using the Coordinated Universal Time (UTC) standard, which is the internationally recognized name for Greenwich Mean Time (GMT). Coordinated Universal Time is the time as measured at zero degrees longitude, the UTC origin point. Daylight saving time is not applicable to UTC.
Local time is relative to a particular time zone. A time zone is associated with a time zone offset, which is the displacement of the time zone measured in hours from the UTC origin point. In addition, local time is optionally affected by daylight saving time, which adds or subtracts an hour from the length of a day. Consequently, local time is calculated by adding the time zone offset to UTC and adjusting for daylight saving time if necessary. The time zone offset at the UTC origin point is zero.
UTC time is suitable for calculations, comparisons, and storing dates and time in files. Local time is appropriate for display in user interfaces of desktop applications. Time zone-aware applications (such as many Web applications) also need to work with a number of other time zones.
If the Kind property of a DateTime object is DateTimeKind.Unspecified, it is unspecified whether the time represented is local time, UTC time, or a time in some other time zone.
A calculation using a DateTime structure, such as Add or Subtract, does not modify the value of the structure. Instead, the calculation returns a new DateTime structure whose value is the result of the calculation.
Conversion operations between time zones (such as between UTC and local time, or between one time zone and another) take daylight saving time into account, but arithmetic and comparison operations do not.
Calculations and comparisons of DateTime objects are meaningful only if the objects represent times in the same time zone. You can use a TimeZoneInfo object to represent a DateTime value's time zone, although the two are loosely coupled. (That is, a DateTime object does not have a property that returns an object that represents that date and time value's time zone other than the Kind property.) For this reason, in a time zone-aware application, you must rely on some external mechanism to determine the time zone in which a DateTime object was created. For example, you could use a structure that wraps both the DateTime value and the TimeZoneInfo object that represents the DateTime value's time zone. For details on using UTC in calculations and comparisons with DateTime values, see Performing Arithmetic Operations with Dates and Times.
DateTime vs. TimeSpan
The DateTime and TimeSpan value types differ in that a DateTime represents an instant in time whereas a TimeSpan represents a time interval. This means, for example, that you can subtract one instance of DateTime from another to obtain a TimeSpan object that represents the time interval between them. Or you could add a positive TimeSpan to the current DateTime to obtain a DateTime value that represents a future date.
You can add or subtract a time interval from a DateTime object. Time intervals can be negative or positive, can be expressed in units such as ticks or seconds, or can be expressed as a TimeSpan object.
COM Interop Considerations
A DateTime value that is transferred to a COM application, then is transferred back to a managed application, is said to round-trip. However, a DateTime value that specifies only a time does not round-trip as you might expect.
If you round-trip only a time, such as 3 P.M., the final date and time is December 30, 1899 C.E. at 3:00 P.M., instead of January, 1, 0001 C.E. at 3:00 P.M. This happens because the .NET Framework and COM assume a default date when only a time is specified. However, the COM system assumes a base date of December 30, 1899 C.E. while the .NET Framework assumes a base date of January, 1, 0001 C.E.
When only a time is passed from the .NET Framework to COM, special processing is performed that converts the time to the format used by COM. When only a time is passed from COM to the .NET Framework, no special processing is performed because that would corrupt legitimate dates and times on or before December 30, 1899. This also means if a date starts its round-trip from COM, the .NET Framework and COM preserve the date.
The behavior of the .NET Framework and COM means that if your application round-trips a DateTime that only specifies a time, your application must remember to modify or ignore the erroneous date from the final DateTime object.