The DateTime Data Type
So far in the C# Fundamentals tutorial we have considered the storage and manipulation of numeric and textual data. When you wish to process date and time information, neither provides a satisfactory solution. A much better option is the DateTime structure.
The DateTime structure describes an instant in time, holding both a date and a time. The date part holds a date, month and year that can represent dates between 1 January 0001 to 31 December 9999, a period of almost ten thousand years. The time part stores times with millisecond accuracy.
As the DateTime data type is a structure rather than an object, it is not possible for variables of this type to hold null values. However, with such a wide range of values available, it is common for a specific date such as 1/1/1 or 31/12/9999 to be used to indicate an undefined date.
Co-ordinated Universal Time
Co-ordinated Universal Time (UTC) is a worldwide standard for defining time. Unlike local times, which vary between time zones and with daylight savings time variations, a UTC time is the same everywhere on the Earth simultaneously. For example, using local times it can be 9:00am in the UK and 10:00am in France. Expressed in UTC, it could be 9:00am in both countries.
UTC time is ideal when storing the time at which events occur. If using local time it is possible for a change in daylight savings time to falsely suggest that events occurred in the wrong order. Using UTC this problem disappears. This is more pronounced when a central application is used internationally.
The DateTime structure allows the creation of date and time values using either local time or UTC. It permits conversion between the two times so that information can be stored accurately and displayed using the user's preference.
The smallest definable time interval is one ten-millionth of a second, or one hundred nanoseconds. This period of time is known as a tick. Ticks provide an accurate method of describing the time in a DateTime by counting the number of ticks since 1 January 0001.
Unlike numeric and textual data types, DateTime variables cannot be assigned using a literal value. Instead, the DateTime structure includes constructors that generate the date and time information required. DateTime values may also be assigned by parsing strings or using special values. Each method is described below.
Possibly the simplest DateTime constructor requires three integer parameters. These represent the year, month and date parts of a date. All DateTime values include both a date part and a time part so for this constructor, the time defaults to midnight. As the range of the integer values is greater than the possible values for the date parts, it is possible to provide invalid arguments and cause an exception.
newDate = new DateTime(2006, 12, 20); // Date is 20 Dec 2006 (midnight)
newDate = new DateTime(2006, 13, 20); // Causes an error to occur
To include a time in a DateTime value, further parameters can be used . Three extra integer parameters can be added to represent hours, minutes and seconds. For greater accuracy a seventh integer parameter can be specified to represent a number of milliseconds.
newDate = new DateTime(2000, 1, 2, 3, 4, 5); // Date = 2 Jan 2000 03:04:05
newDate = new DateTime(2000, 1, 2, 3, 4, 5, 6); // Date = 2 Jan 2000 03:04:05.0006
The most accurate assignment of DateTime uses a number of ticks in a 64-bit integer (or long) parameter. The parameter defines the number of ticks since midnight on 1 January 0001. The number of ticks for an existing date may also be extracted from a DateTime by reading the Ticks property.
newDate = new DateTime(0); // Date = 1 Jan 0001 (midnight)
newDate = new DateTime(630823790450000000); // Date = 2 Jan 2000 03:04:05
long numTicks = newDate.Ticks; // Result = 630823790450000000
When accepting a date entered by a user, it can be difficult to ensure that the correct format is used, particularly for international applications where users in different countries have varying date formats. The Parse method converts strings to DateTime values using local date formats. The example below assumes the use of a UK-configured computer.
newDate = DateTime.Parse("01/02/2006"); // Date = 1 Feb 2006 (midnight)
newDate = DateTime.Parse("02/01/2000 03:04"); // Date = 2 Jan 2000 03:04:00
newDate = DateTime.Parse("02/01/06"); // Date = 2 Jan 2006 (midnight)
NB: There are various overloaded variations of the Parse method that give finer control over the conversion of strings. There is also another method named ParseExact. These are beyond the scope of the C# Fundamentals tutorial.
Assigning the Current Date and Time
The DateTime structure provides three static properties that return the current date or time. The Now property returns the current local date and time. If you only need the date you can use the Today property, which defaults the time to midnight. Finally, when storing times using Co-ordinated Universal Time, the UtcNow property provides the correct UTC date and time.
newDate = DateTime.Now; // Current local time
newDate = DateTime.Today; // Current local date (midnight)
newDate = DateTime.UtcNow; // Current UTC time
MinValue and MaxValue
The last manner to be considered for creating a DateTime value is to use one of two predefined values. These are retrieved from the static properties MinValue or MaxValue. These properties return the minimum or maximum possible DateTime values and are usually used to indicate that a date is undefined where the use of null is not permitted.
newDate = DateTime.MinValue; // 01/01/0001 00:00:00
newDate = DateTime.MaxValue; // 31/12/9999 23:59:59
.NET 2.0 Nullable DateTime
Earlier in the tutorial we examined the nullable numeric data types that were introduced as part of the .NET Framework 2.0. The DateTime data type has a nullable equivalent with similar functionality.
nullableDate = DateTime.MinValue; // Assign a non-null date
nullableDate = null; // Assign an undefined value
20 December 2006