The Date Controls
Retrieving date information is a common task. For example, requiring a date range is a good way to limit database searches. In the past, programmers have used a variety of different controls to retrieve date information, including text boxes that required a specific format of month, date, and year values.
The modern date controls make life much easier. For one thing, they allow dates to be chosen from a graphical calendar view that's easy to use and prevents users from choosing invalid dates (like the 31st day in February, for example). They also allow dates to be displayed in a range of formats.
There are two date controls: DateTimePicker and MonthCalendar. DateTimePicker is ideal for choosing a single date value, and requires the same amount of space as an ordinary drop-down list box. When the user clicks the drop-down button, a full month calendar page is shown. The user can page from month to month (and even year to year) looking for a specific date with the built-in navigational controls. The control handles these details automatically.
The MonthCalendar shows a similar expanded display, with a single month at a time. Unlike the DateTimePicker, it allows the user to choose a range of dates. Both controls are shown in Figure 4-8.

Figure 4-8: The date controls
The DateTimePicker
The DateTimePicker allows a user to choose a single date. One nice thing about the DateTimePicker is that it automatically takes the computer's regional settings into consideration. That means you can specify Short for the DateTimePicker.Format property, and the date might be rendered as yyyy/mm/dd format or dd/mm/yyyy depending on the date settings. Alternatively, you can specify a custom format by assigning a format string to the CustomFormat property, and make sure the date is always presented in the same way on all computers. Figure 4-9 shows the different date formats.

Figure 4-9: Common date formats
The selected date is provided in the Value property. One important detail about date controls is that they always use the System.DateTime date type, which represents a date and time. Depending on your needs, you might configure a date control to show only the day or time portion. In this case, you may need to be careful to retrieve just the appropriate part.
For example, imagine you are using a DateTimePicker control, which allows the user to choose the start date for a database search. The date control is configured to show dates in the long format, which doesn't include time information.
When the form loads, you configure the date control:
dtStart.Value = DateTime.Now; // Sets dtStart to the current date and time.
The user might then click a different date. However, choosing a different date only updates the month, year, and day components of the date. The time component remains, even though it is not displayed!
// The next line performs a search based on date and the original time.
// This artificially limits the returned results.
string SQLSelect = "SELECT * FROM Orders WHERE Date >'" +
dtStart.Value.ToString() + "'";
If you initialized the DateTimePicker at lunchtime, you could lose the first half day from your search.
There are a number of ways to avoid this problem. For example, you can use the DateTime.Date property, which returns another DateTime object that has its time portion set to 0 (midnight).
// This gets the full day.
string SQLSelect = "SELECT * FROM Orders WHERE Date >'" +
dtStart.Value.Date.ToString() + "'";
You could also use the DateTime.Today property to set the initial value instead of DateTime.Now. This is a good technique for the MonthCalendar control as well. The MonthCalendar automatically sets the time component for the currentValue to 0 when the user selects a date, but if the user leaves the default date unchanged, and you've assigned a date with information, the time portion remains.
You can also use a DateTimePicker to represent a time value with no date component. To do so, set the Format property to Time. You also need to set the UseUpDown property to true. This prevents the drop-down month display from being shown. Use the up/down scroll buttons instead to increment the highlighted time component (hours, minutes, or seconds).
Table 4-9 lists the important properties of the DateTimePicker control.
Table 4-9: DateTimePicker Properties
PropertiesDescription
CalendarFont, CalendarForeColor, CalendarMonthBackground, CalendarTitleBackColor, CalendarTitleForeColor, and CalendarTrailingForeColorThese properties configure the calendar's font and the color used for parts of its interface. The default colors are provided as static read-only fields for this class (like DefaultTitleForeColor). Note that the CalendarTrailingForeColor changes the color of the "trailing" dates. These are the dates that appear on a month page from the previous month (at the beginning) or from the next month (at the end). They are used to fill in the grid.
ShowCheckBox and CheckedShowCheckBox displays a small check box inside the drop-down list box. Unless it is checked, the date cannot be modified.
Format and CustomFormatThe Format property specifies a value from the DateTimePickerFormat enumeration. Alternatively, you can manually specify an exact form by assigning a format string to the CustomFormat property (like "yyyy/MM/DD hh:mm:ss").
DropDownAlignDetermines whether the drop-down month page lines up with the left or right of the list box.
MaxDate and MinDateSets a maximum and minimum date, beyond which the user cannot select. This is a great tool for preventing error messages by making invalid selections impossible.
ShowUpDownWhen set to true, disables the drop-down month pages and uses up/down scroll buttons for incrementing part of the date. This is ideal for time-only values.
Text and ValueText returns the formatted date as a string, according to how it is currently displayed. Value returns the represented DateTime object.
MonthCalendar
The MonthCalendar control looks like the DateTimePicker, except that it always shows the month page display, and it doesn't allow the user to enter a date by typing it into a list box. That makes the MonthCalendar slightly less useful, except for situations when you need to let the user select a range of contiguous dates.
You set the maximum number of dates that the user can select in the MaxSelectionCount property. The user selects a group of dates by dragging and clicking. Selected dates must always be next to each other. The first and last selected dates are returned as DateTime objects in the SelectionStart and SelectionEnd properties. Figure 4-10 shows a range of four days.

Figure 4-10: Selecting multiple dates
// Set a range of four days.
dt.SelectionStart = new DateTime(2003, 01, 17);
dt.SelectionEnd = new DateTime(2003, 01, 20);
Depending on your needs, you may still need to perform a significant amount of validation with selected dates to make sure they fit your business rules. Unfortunately, you can't easily use the DateChanged and DateSelected events for this purpose. They only fire after an invalid date has been selected, and you have no way to remove the selection unless you choose a different date range. Information about the original (valid) date range is already lost.
Though the MonthCalendar control looks similar to the DateTimePicker, it provides a different set of properties, adding some features while omitting others. Table 4-10 lists the most important properties.
Table 4-10: MonthCalendar Properties
PropertyDescription
AnnuallyBoldedDates, MonthlyBoldedDates, and BoldedDatesThese properties accept arrays of DateTime objects, which are then shown in bold in the calendar. MonthlyBoldedDates can be set for one month and are repeated for every month, while AnuallyBoldedDates are set for one year and repeated for every year.
FirstDayOfWeekSets the day that will be shown in the leftmost column of the calendar.
MaxDate, MinDate, and MaxSelectionCountSets the maximum and minimum selectable date in the calendar, and the maximum number of contiguous dates that can be selected at once.
ScrollChangeThe number of months that the calendar "scrolls through" every time the user clicks a scroll button.
SelectionEnd, SelectionStart, and SelectionRangeIdentifies the selected dates. The SelectionRange property returns a special structure that contains a SelectionEnd and SelectionStart date.
ShowToday and ShowTodayCircleThese properties, when true, show the current day in a special line at the bottom of the control and highlight it in the calendar with a circle, respectively.
ShowWeekNumbersIf true, displays a number next to each week in the year from 1 to 52.
TodayDate and TodayDateSetTodayDate indicates what date is shown as "today" in the MonthCalendar. If you set this value manually in code, TodayDateSet is true.
TitleBackColor, TitleForeColor, and TrailingForeColorSets colors associated with the MonthCalendar. Note that the TrailingForeColor changes the color of the "trailing" dates. These are the dates that appear on a month page from the previous month (at the beginning) or from the next month (at the end). They are used to fill in the grid.
Caution
The MonthCalendar control doesn't properly support Windows XP styles. If you try to use this control with a project that uses Windows XP styles, the display does not appear correctly when the user selects more than one date at a time.