Date and Time Values

Before you can fully understand date and time controls, you must first be familiar with how the .NET Framework deals with date and time values. Two different structures are provided for representing dates and times. The DateTime structure represents a specific point in time, while the TimeSpan structure represents a length of time. These structures are described in the next two sections.

16.2.1 DateTime Structure

Date and time values in the .NET Framework are typically represented with a DateTime structure. This structure is a value type representing a point in time, typically expressed with both a date and a time component. Like a class, it has constructors, fields, properties and methods, plus several operators, all for the purpose of allowing your code to represent and manipulate date and time values.

Time values in the .NET Framework are measured in units of ticks, each 100 nanoseconds long. Dates are measured as the number of ticks since midnight, January 1, 1 C.E. in the Gregorian calendar, unless a different calendar is explicitly specified.

The civil calendar in common use today is called the Gregorian calendar, named after Pope Gregory XIII. In 1582 he ordered changes to the calendar then in use to correct errors arising from the fact that a solar year is approximately 11 minutes short of 365 1/4 days. It is nominally based on the year of the birth of Jesus. Years prior to the birth of Jesus are referred to either as B.C. (Before Christ) or B.C.E. (Before the Common Era), and years after the birth of Jesus are referred to as A.D. (Latin abbreviation for Anno Domini, which translates to "in the year of the Lord") or C.E. (Common Era). The German astronomer Johannes Kepler (1571-1630) later showed that Jesus was actually born in the year 4 B.C.E.

Time values can be either positive or negative. They can be expressed in units of ticks, seconds, hours, or in instances of TimeSpan (described below). Time values can be added to or subtracted from DateTime objects. All DateTime calculations assume the same time zone, so your program must take differing time zones into account. All methods and properties of the DateTime class use the local time zone.

There are seven overloaded forms of the DateTime structure's constructor. Table 16-1 lists the arguments for each different constructor.

Table 16-1. DateTime constructors

Argument types

Description

Long

Number of ticks.

Integer, integer, integer

Year (1 through 9999), month (1 through 12), and day (1 through number of days in month).

Integer, integer, integer, Calendar

Year, month, and day using the specified calendar object.

Integer, integer, integer, integer, integer, integer

Year, month, day, hour (0 through 23), minute (0 through 59), and seconds (0 through 59).

Integer, integer, integer, integer, integer, integer, Calendar

Year, month, day, hour, minute, and seconds using the specified calendar object.

Integer, integer, integer, integer, integer, integer, integer

Year, month, day, hour, minute, seconds, and milliseconds.

Integer, integer, integer, integer, integer, integer, integer, Calendar

Year, month, day, hour, minute, seconds, and milliseconds using the specified calendar object.

The DateTime structure has two public read-only fields. MaxValue represents the largest possible value, corresponding to one tick before January 1, 10000, or 23:59:59.9999999 December 31, 9999. MinValue represents the smallest possible value, corresponding to 00:00:00.0000000 January 1, 0001.

A number of read-only properties, some static (Shared in VB.NET), provide date-time functionality, listed in Table 16-2.

Table 16-2. DateTime properties

Property

Value type

Description

Date

DateTime

The date component of the DateTime instance, with the time set to 12:00 AM (midnight 00:00:00).

Day

Integer

The day of the month of the DateTime instance. An integer between 1 and 31, inclusive.

DayOfWeek

DayOfWeek

The day of the week enumerated constant. Sunday corresponds to zero, Monday to one, and so forth.

DayOfYear

Integer

The day of the year, between 1 and 366, inclusive, of the DateTime instance.

Hour

Integer

The hour component of the DateTime instance. An integer between 0 and 23, inclusive.

Millisecond

Integer

The millisecond component of the DateTime instance. An integer between 0 and 999, inclusive.

Minute

Integer

The minute component of the DateTime instance. An integer between 0 and 59, inclusive.

Month

Integer

The month component of the DateTime instance. An integer between 1 and 12, inclusive.

Now

DateTime

Static. The current local date and time. The resolution depends on the OS: 55 milliseconds under Win98, 16 milliseconds under WinNT 3.1, and 10 milliseconds under WinNT 3.5 and later.

Second

Integer

The seconds component of the DateTime instance. An integer between 0 and 59, inclusive.

Ticks

Long

The number of 100 nanosecond ticks representing the DateTime instance. It is a number between MinValue and MaxValue.

TimeOfDay

TimeSpan

The span of time since midnight of the current day.

Today

DateTime

Static. The current local date. The time portion of the DateTime is 12:00 AM (midnight 00:00:00).

UtcNow

DateTime

Static. The current local date and time expressed as coordinated universal time (UTC), previously known as Greenwich Mean Time (GMT). The resolution is the same as for the Now property.

Year

Integer

The year component of the DateTime instance. An integer between 1 and 9999, inclusive.

The DateTime methods, the most commonly used of which are listed in Table 16-3, perform DateTime manipulation, such as adding and subtracting date-time values, comparing values, and converting from one format to another.

Table 16-3. DateTime methods

Method

Description

Add

Adds TimeSpan object to DateTime. Returns a new DateTime.

AddDays

Adds number of whole and fractional days, positive or negative, to DateTime. Returns a new DateTime.

AddHours

Adds number of whole and fractional hours, positive or negative, to DateTime. Returns a new DateTime.

AddMilliseconds

Adds number of whole and fractional milliseconds, positive or negative, to DateTime. Returns a new DateTime.

AddMinutes

Adds number of whole and fractional minutes, positive or negative, to DateTime. Returns a new DateTime.

AddMonths

Adds integer number of months, positive or negative, to DateTime. Returns a new DateTime.

AddSeconds

Adds number of whole and fractional seconds, positive or negative, to DateTime. Returns a new DateTime.

AddTicks

Adds number of ticks, positive or negative, to DateTime. Returns a new DateTime.

AddYears

Adds integer number of years, positive or negative, to DateTime. Returns a new DateTime.

Compare

Static. Compares two DateTime objects. Returns zero if they are equal, less then zero if the first is less than the second, and greater then zero if the first is greater than the second.

CompareTo

Compares this instance to a specified DateTime object. Returns same as Compare method, except it also returns greater than zero if specified DateTime object is null (Nothing).

DaysInMonth

Static. Returns number of days in specified year and month (number from 1 to 12). Takes leap year into account.

Equals

Overloaded. Static version returns true if two DateTimes represent the same date-time value. Instance version returns true if DateTime represents the same date-time value as the instance.

FromFileTime

Static. Returns DateTime object representing OS file timestamp.

GetDateTimeFormats

Overloaded. Returns string array containing all the representations supported by standard DateTime format specifiers.

IsLeapYear

Static. Returns true if specified year is leap year, false otherwise.

Parse

Static. Overloaded. Converts specified string to DateTime object.

ParseExact

Static. Overloaded. Converts specified string, which must precisely match a specified format, to DateTime object.

Subtract

Overloaded. Subtracts the specified DateTime or TimeSpan and returns a TimeSpan or DateTime object, respectively.

ToFileTime

Converts this instance to local system file time format, which is 64-bit unsigned value representing number of ticks since January 1, 1601 12:00 AM.

ToLocalTime

Returns local DateTime object equivalent to current UTC time adjusted for local time zone and daylight saving time.

ToLongDateString

Returns equivalent long date string representation, containing name of the day, name of the month, numeric day of month, and year. Equivalent to ToString or to using "D" format character from Table 16-10.

ToLongTimeString

Returns equivalent long time string representation. Equivalent to using "T" format character from Table 16-10.

ToShortDateString

Returns equivalent short date string representation, containing numeric month, numeric day of month, and year. Equivalent to using "d" format character from Table 16-10.

ToShortTimeString

Returns equivalent short time string representation. Equivalent to using "t" format character from Table 16-10.

ToString

Overloaded, overrides. Returns string representation, optionally using specified format and culture information.

ToUniversalTime

Returns UTC DateTime object equivalent to current local time.

The DateTime structure provides several arithmetic and logical operators, listed in Table 16-4. All of these operators have equivalent methods.

Table 16-4. DateTime operators

Operator

Description

Addition

Adds a DateTime and a TimeSpan, returning a DateTime. In C#, use the plus sign (+). In VB.NET, use DateTime.op_Addition. Equivalent to Add method.

Equality

Returns true if two DateTimes are equal. In C#, use two equal signs (==). In VB.NET, use DateTime.op_Equality. Equivalent to Equals method.

Greater Than

Returns true if first DateTime is greater than the second. In C#, use the greater-than sign (>). In VB.NET, use DateTime.op_GreaterThan. Equivalent to Compare method.

Greater Than or Equal

Returns true if first DateTime is greater than the second. In C#, use the greater than or equal signs (>=). In VB.NET, use DateTime.op_GreaterThanOrEqual. Equivalent to Compare method.

Inequality

Returns true if the two DateTimes do not represent the same date and time. In C#, use the inequality signs (!=). In VB.NET, use DateTime.op_Inequality. Equivalent to Equals method.

Less Than

Returns true if first DateTime is less than the second. In C#, use the less-than sign (<). In VB.NET, use DateTime.op_LessThan. Equivalent to Compare method.

Less Than or Equal

Returns true if first DateTime is less than or equal to the second. In C#, use the less than or equal signs (<=). In VB.NET, use DateTime.op_LessThanOrEqual. Equivalent to Compare method.

Subtraction

Overloaded. Either subtracts one DateTime from another, returning a TimeSpan, or subtracts a TimeSpan from a DateTime, returning a DateTime. In C#, use the minus sign (-). In VB.NET, use DateTime.op_Subtraction. Equivalent to Subtract method.

16.2.2 TimeSpan Structure

The TimeSpan object, also a structure, represents a period of time, in number of ticks. TimeSpan values can be either positive or negative. It resembles the DateTime object in constructors, properties, methods and operators, with just enough differences to drive you crazy.

There are four overloaded forms of the constructor for the TimeSpan structure. Table 16-5 lists the arguments for each constructor.

Table 16-5. TimeSpan constructors

Argument types

Description

long

Number of ticks.

integer, integer, integer

Hours, minutes, and seconds.

integer, integer, integer, integer

Days, hours, minutes, and seconds.

integer, integer, integer, integer, integer

Days, hours, minutes, seconds, and milliseconds.

The string representation of TimeSpan objects includes components for the sign, days, hours, minutes, seconds, and fractional seconds to seven decimal places, of the form [-][d.]hh:mm:ss[.ff], where characters in brackets are optional. So, for example, you could create a new TimeSpan object with the following line of code:

TimeSpan ts = new TimeSpan(1,2,10,10,500)

This TimeSpan instance would represent a period of 1 day, 2 hours, 10 minutes, 10 seconds, and 500 milliseconds. The string representation of this object, obtained by using the ToString method listed in Table 16-7, would be:

1.02:10:10.5000000

Conversely, the Parse method, also listed in Table 16-7, can convert strings to TimeSpan objects. So for example, the following two lines of code:

TimeSpan ts = new TimeSpan( ) ts = TimeSpan.Parse("-1:15:15.1234")

result in a TimeSpan object representing negative one hour, 15 minutes, 15.1234 seconds, with the following string representation:

-01:15:15.1234000

The properties of the TimeSpan structure, all of which are read-only and apply to specific instances of the structure, are listed in Table 16-6.

Table 16-6. TimeSpan properties

Property

Value type

Description

Days

Integer

Read-only. The day component of the TimeSpan object.

Hours

Integer

Read-only. The hour component of the TimeSpan object.

Milliseconds

Integer

Read-only. The millisecond component of the TimeSpan object.

Minutes

Integer

Read-only. The minute component of the TimeSpan object.

Seconds

Integer

Read-only. The second component of the TimeSpan object.

Ticks

Long

Read-only. The number of 100 nanosecond ticks contained in the TimeSpan object.

TotalDays

Double

Read-only. The number of whole and fractional days contained in the TimeSpan object.

TotalHours

Double

Read-only. The number of whole and fractional hours contained in the TimeSpan object.

TotalMilliseconds

Double

Read-only. The number of whole and fractional milliseconds contained in the TimeSpan object.

TotalMinutes

Double

Read-only. The number of whole and fractional minutes contained in the TimeSpan object.

TotalSeconds

Double

Read-only. The number of whole and fractional seconds contained in the TimeSpan object.

The commonly used methods of the TimeSpan structure are listed in Table 16-7. Notice that some methods are static (shared in VB.NET).

Table 16-7. TimeSpan methods

Method

Description

Add

Adds TimeSpan object to TimeSpan. Returns a new TimeSpan.

Compare

Static. Compares two TimeSpan objects. Returns zero if they are equal, less then zero if the first is less than the second, and greater then zero if the first is greater than the second.

CompareTo

Compares this instance to a specified TimeSpan object. Returns the same as Compare method, except it also returns greater than zero if specified TimeSpan object is null (Nothing).

Duration

Returns a TimeSpan object that is the absolute value (i.e., always positive) of this TimeSpan instance.

Equals

Overloaded. Static version returns true if two TimeSpans represent the same value. Instance version returns true if the specified TimeSpan represents the same value as the instance.

FromDays

Static. Returns a TimeSpan representing the specified number of days, accurate to the nearest millisecond.

FromHours

Static. Returns a TimeSpan representing the specified number of hours, accurate to the nearest millisecond.

FromMilliseconds

Static. Returns a TimeSpan representing the specified number of milliseconds.

FromMinutes

Static. Returns a TimeSpan representing the specified number of minutes, accurate to the nearest millisecond.

FromSeconds

Static. Returns a TimeSpan representing the specified number of seconds, accurate to the nearest millisecond.

FromTicks

Static. Returns a TimeSpan representing the specified number of ticks.

Negate

Returns a TimeSpan object with the same value as the instance, but of the opposite sign.

Parse

Static. Converts specified string to TimeSpan object.

Subtract

Subtracts the specified TimeSpan and returns a TimeSpan object.

ToString

Returns a string representation of the TimeSpan instance in the form [-][d.]hh:mm:ss[.ff], where characters in brackets are optional. Does not accept any formatting strings as arguments.

The TimeSpan structure provides several arithmetic and logical operators, listed in Table 16-8. Except for the two unary operators, all of these operators have equivalent methods.

Table 16-8. TimeSpan operators

Operator

Description

Addition

Adds two TimeSpan objects, returning a TimeSpan. In C#, use the plus sign (+). In VB.NET, use TimeSpan.op_Addition. Equivalent to Add method.

Equality

Returns true if two TimeSpans are equal. In C#, use the two equal signs (==). In VB.NET, use TimeSpan.op_Equality. Equivalent to Equals method.

Greater Than

Returns true if first TimeSpan is greater than the second. In C#, use the greater-than sign (>). In VB.NET, use TimeSpan.op_GreaterThan. Equivalent to Compare method.

Greater Than or Equal

Returns true if first TimeSpan is greater than the second. In C#, use the greater than or equal signs (>=). In VB.NET, use TimeSpan.op_GreaterThanOrEqual. Equivalent to Compare method.

Inequality

Returns true if the two TimeSpans do not represent the same value. In C#, use the inequality signs (!=). In VB.NET, use TimeSpan.op_Inequality. Equivalent to Equals method returning the opposite value.

Less Than

Returns true if first TimeSpan is less than the second. In C#, use the less-than sign (<). In VB.NET, use TimeSpan.op_LessThan. Equivalent to Compare method.

Less Than or Equal

Returns true if first TimeSpan is less than or equal to the second. In C#, use the less-than or equal signs (<=). In VB.NET, use TimeSpan.op_LessThanOrEqual. Equivalent to Compare method.

Subtraction

Subtracts one TimeSpan from another, returning a TimeSpan. In C#, use the minus sign (-). In VB.NET, use TimeSpan.op_Subtraction. Equivalent to Subtract method.

Unary Negation

Returns a TimeSpan with the same numeric value as the specified TimeSpan but of opposite sign. In C#, use the minus sign (-). In VB.NET, use TimeSpan.op_UnaryNegation.

Unary Plus

Returns the specified TimeSpan. In C#, use the plus sign (+). In VB.NET, use TimeSpan.op_UnaryPlus.

You will see many of these DateTime and TimeSpan members used throughout this chapter, especially in the CountDownTimer application in Example 16-6 and Example 16-7.

16.2.3 Date and Time Format Strings

There are an infinite number of ways to format text representations of date and time. Days and months can be expressed as single digits, two digits, abbreviations of names, or full names. Hours can be single digits or two digits in a 12-hour format, either followed by AM/PM, A/P, or nothing, or in 24-hour format. Years can be one, two, or four digits. Times can include seconds or milliseconds, or neither. This list doesn't even begin to include all the custom formats you or your clients can dream up: "Saturday, the 8th of January, `05 at 2:08 in the afternoon," for example.

Looking at the DateTime methods in Table 16-3, you see several methods that convert to long and short date and time strings. These and other methods and properties depend on the regional settings of the end-user machine.

The Regional settings for a machine are set via Regional Options in the Control Panel. In Windows 2000, the Locale is set in the General tab of the Regional Options dialog box. Time and Date tabs customize time formats and both short and long date formats. In Windows XP, the Locale is set in the Regional Options tab of the Regional and Language Options dialog box, and the time and date formats are customized by clicking the Customize button. Both operating systems use the formatting characters listed in Table 16-9.

In addition, the DateTime.ToString method listed in Table 16-3, which overrides Control.ToString, has overloaded forms that take format strings to allow you to customize the resulting string. Those format strings are comprised of the characters found in Tables Table 16-9 and Table 16-10. If a string contains characters contained in both Tables Table 16-9 and Table 16-10, the meaning listed in Table 16-10 will prevail.

As you will see in the next section, the DateTimePicker control has two properties that control how the date-time value is displayed in the control. The Format property determines if the display format is Short, Long, Time, or Custom. If it is set to DateTimePickerFormat.Custom, then the CustomFormat property must contain a text string comprised of the formatting characters contained in Table 16-9.

Literal string characters can be included in format strings. If there is any ambiguity about whether the characters will be interpreted as literal strings or formatting characters, they should be escaped using single quotes, as shown in examples later in the chapter.

Table 16-9. DateTime format strings

Format string

Description

d

One- or two-digit days.

dd

Two-digit days. Single-digit values are padded with a leading zero.

ddd

Three-character day of the week abbreviatione.g., Mon.

dddd

Full day of the week namee.g., Monday.

h

One- or two-digit hours in 12-hour format.

hh

Two-digit hours in 12-hour format. Single-digit values are padded with a leading zero.

H

One- or two-digit hours in 24-hour format.

HH

Two-digit hours in 24-hour format. Single-digit values are padded with a leading zero.

m

One- or two-digit minutes.

mm

Two-digit minutes. Single-digit values are padded with a leading zero.

M

One- or two-digit month.

MM

Two-digit month. Single-digit values are padded with a leading zero.

MMM

Three-character month abbreviatione.g., Jan.

MMMM

Full month namee.g., January.

s

One- or two-digit seconds.

ss

Two-digit seconds. Single-digit values are padded with a leading zero.

t

One-letter AM/PM abbreviatione.g., A.

tt

Two-letter AM/PM abbreviatione.g., AM.

y

One-digit yeare.g., 2001 is "1".

yy

Last two digits of the year.

yyyy

Full year.

Table 16-10. DateTimeFormatInfo format characters

Format string

Description

d

Short datee.g., M/d/yyyy

D

Long datee.g., dddd, dd MMMM yyyy

f

Full datee.g., dddd, MMMM dd, yyyy hh:mm tt

F

Full datee.g., dddd, MMMM dd, yyyy hh:mm:ss tt

g

Generale.g., M/d/yyyy hh:mm tt

G

Generale.g., M/d/yyyy hh:mm:ss tt

m, M

Month and daye.g., MMMM dd

r, R

RFC1123e.g., ddd,dd MMM yyyy HH':'mm':'ss `GMT'

s

Sortable DateTimee.g., yyyy'-'MM'-'dd'T'HH':'mm':'ss

t

Short timee.g., hh:mm tt

T

Long timee.g., hh:mm:ss tt

u

Universal sortable DateTimee.g., yyyy'-'MM'-'dd HH':'mm':'ss'Z'

U

Full date and time using universal timee.g., dddd, MMMM dd, yyyy hh:mm:ss tt

y,Y

YearMonthe.g., MMMM, yyyy

Категории