Using Date and Time Values

Visual Basic .NET provides the versatile Date data type to store date and time values. The following lines of code are examples of using date variables:

Dim dtWWII As Date = #12/7/1941# 
Dim dtKing As Date = Convert.ToDateTime("Aug 16, 1977 4:00 PM") 
Dim dtJFK As Date = Convert.ToDateTime("November 23, 1963") 
Dim dtMoon As New Date(1969, 7, 20) 

The first line of the previous code uses the pound (#) symbol to assign a date value directly to a variable of type date. The next two examples use methods to convert strings containing date and time expressions to the Date type. The final line of code shows how the constructor method can be used to initialize a date by supplying parameters for the year, month, and day.

Depending on how you need to use dates in your program, you may use any of the preceding methods. Listed next are a couple of points to keep in mind when working with the Date data type:

  1. The Date data type always stores a date and a time value to the millisecond, whether or not you need both parts. As we will see, there are methods and properties to extract only the parts you need for display or calculation purposes.

  2. Visual Basic’s Date data type is based on the .NET DateTime data type, so some of the functions (such as Convert.ToDateTime) will reference the .NET spelling. When declaring variables you may use either.

In this section,we will explore some of the functions used to manipulate date and time values.

Determining the Current Date and Time

It is often useful to determine the current system date and time in a Visual Basic program. Some possible uses for the system date and time are:

  • Logging when program actions occur.

  • Running a job or performing some action periodically.

  • Measuring the speed of your application.

There are a couple of different functions, Now and Today, that return a Date value containing the current system time. Now returns the current date and time; Today returns the current date with the time set to midnight. For example, these two lines of code produce different output:

Debug.WriteLine(Date.Now) 
Debug.WriteLine(Date.Today) 

If today were February 27, 2001 at 6:45 P.M. the following values would be returned:

2/27/2001 06:45:00 PM 
2/27/2001 12:00:00 AM 

Note the output of Today does not include the current time, which is useful when doing date-range comparisons.

Date and Time Formats

The previous sample lines show the default date/time format when a Date value is converted to a string. However, when displaying dates on a report or in a text box you may want to use a more readable format. As with numbers, you can create a format string to determine which parts of the date are displayed. By placing characters in the format string that represent the desired parts of the date, you can build your own custom date format. Table 6.6 lists some examples of format strings and the outputs they produce for August 16, 1945, 1:15 P.M.

Table 6.6. Examples of Date and Time Format Strings
Format String Output String
M/d/yy 8/16/45
MM/dd/yyyy 08/16/1945
MM/dd hh:mm:ss tt 08/16 01:15:00 PM
MMMM d, yyyy H:mm August 16, 1945 13:15
dddd, MMM d, yyyy Thursday, Aug 16, 1945

Note

Date and time format strings are case-sensitive. For example, M refers to the month and m refers to the minute. A complete list of the characters you can use to build a format string is included in the help files under the topic User-Defined Date/Time Formats.


To change the format of a date, pass the format string as a parameter to the Format function or the ToString method of a date object. The following sample lines of code show how to use date formatting:

Dim TheDate As Date = Now 
Dim OutputString1, OutputString2 As String 
OutputString1 = Format(TheDate, "M/d/yy") 
OutputString2 = TheDate.ToString("M/d/yy") 

As you can see, the Format function works the same way it does for numbers. If you do not specify a format and simply convert your date value to a string, the output may be affected by settings in your Windows Control Panel. (We will discuss this more in the upcoming section called “Understanding Regional Settings.”)

Note

The output of the Format method/function is a string. To convert a string back to a date, you can use the Convert.ToDateTime method, as shown in an earlier example. However, make sure that the string is a valid date or an exception will occur.


Extracting Parts of a Date

If you need to work with dates in an automated fashion, you might want to extract just part of a date. Suppose, for example, you need to schedule a process to back up files every Saturday. As you saw in the last section, you can use the Format function to get a string containing just the parts of a date you want, including the day of the week. However, a date object also contains several properties that can be used to more easily extract a specific portion of a date. In our example, the DayOfWeek property could be used to check the current day of the week:

If Now.DayOfWeek = 6 Then BackUpFiles() 

In the previous line of code, we used the DayOfWeek property to determine the current day of the week, but DayOfWeek can be used with any date object. It returns an Integer value directly, and is more efficient than comparing strings using the Format method. A complete list of properties used to extract date parts are listed in Table 6.7

Table 6.7. Properties Used to Obtain Specific Parts of a Date
Property Name Information Returned Type Returned
Date Date Only Date
TimeofDay Time Only TimeSpan
Month Month (1–12) Integer
Day Day of the Month (1–31) Integer
Year Year Integer
Hour Hour (0–23) Integer
Minute Minute (0–59) Integer
Second Second (0–59) Integer
Millisecond Millisecond (0–999) Integer
DayOfWeek Weekday Number (0–6) Integer
DayOfYear Day of Year (1–366) Integer
Ticks Ticks since 1/1/0000 Long

Note

When extracting parts of a date, users of previous versions of Visual Basic may also be familiar with functions such as DatePart, Year, Month, and Day. These functions are still supported in Visual Basic .NET. However, the authors feel the new properties described here are a better fit with object-oriented coding practices.


Most of the properties listed in Table 6.7 are fairly self-explanatory. However, a new type (TimeSpan) and a new time format (Tick) are introduced. These will be discussed in the upcoming section “Working with Time Intervals.”

Working with Date Intervals

One advantage of using a Date variable to store dates and times (rather than an integer or string) is that it provides a large amount of built-in functionality to manipulate the date. As we have already seen, date values can be formatted and parsed into parts very easily. Even more useful is the ability to add, subtract, and compare date values just as you would numbers. For example, suppose you are managing the construction of thousands of hotels. Thirty days prior to the opening date of the hotel, you need to send a form letter to the owner reminding him of the upcoming opening. The following sample function uses the AddDays method of the Date class to determine whether the letter needs to be sent:

Private Function NeedToSendLetter(ByVal OpeningDate As Date) As Boolean 

      Dim ThirtyDaysAgo As Date 

      'Subtract 30 days from system date 
      ThirtyDaysAgo = Date.Today.AddDays(-30) 

      'Check if opening date is within 30 day range 
      If OpeningDate >= ThirtyDaysAgo And OpeningDate <= Date.Today Then 
           Return True 
      Else 
           Return False 
      End If 

End Function 

As you can see from the sample code, the AddDays method of a Date object returns a date value. This date value is determined by adding the number of days passed as a parameter to the date stored in a Date object. This function also demonstrates that dates can be compared using the same operators used with numeric values, such as greater than or equal to (>=).

Note

There are functions built into the date class to add all types of intervals, such as AddHours, AddMinutes, and AddMilliseconds. When you type a period after the name of a date object in the Code Editor, the automatic statement completion function will show you a list of these methods.


We have just seen how to add a specified number of intervals to a date. However, if you want to determine the number of intervals between two dates, use the DateDiff function. The DateDiff function accepts a constant representing the type of interval, and the dates you want to compare. It returns a double value representing the number of intervals between the two dates. If we go back to our example of tracking opening dates of hotels, we could easily use the DateDiff function to determine the number of days between the opening date and today:

Private Function DaysUntilOpening(ByVal OpenDate As Date) As Long 

Return DateDiff(DateInterval.Day, Date.Today, OpenDate) 

End Function 

The sample function DaysUntilOpening returns the number of days between the opening date and today. Note that the DateDiff function will return a negative number if the second date parameter is less than the first, or zero if the two dates are on the same day. In our example, the caller of the DaysUntilOpening would know that the hotel is already open if the value returned was less than or equal to zero.

Working with Time Intervals

Another special type, TimeSpan, contains members for working with periods of time. As you saw in Table 6.7, the TimeOfDay method of a date object returns a TimeSpan that represents the period of time since midnight. However, time spans represent time intervals independent of a date. The following code demonstrates some methods of the TimeSpan class:

Dim MyInterval As TimeSpan 

MyInterval = TimeSpan.FromMinutes(12345) 

Debug.WriteLine("Number of Days: " & MyInterval.Days) 
Debug.WriteLine("Number of Hours: " & MyInterval.Hours) 
Debug.WriteLine("Number of Ticks: " & MyInterval.Ticks) 

In the sample code, we created a TimeSpan variable called MyInterval that represents a period of time of 12,345 minutes. We then used methods of the TimeSpan class to display other types of intervals within the time period. The output from the previous lines of code is

Number of Days: 8 
Number of Hours: 13 
Number of Ticks: 7407000000000 

Notice that the output for the Timespan.Ticks property is a huge number. A tick is the most precise measure of time in Visual Basic. It represents a time interval of 100 nanoseconds and can be stored in a variable of type Long. The Ticks property of any date value contains the number of ticks since 1/1/0000. One use for ticks is measuring the performance of your application.

→ For more on measuring performance, see Chapter 26, “Debugging and Performance Tuning,” p.717

Handling Two-Digit Year Input

Historians will no doubt look back in amusement at late 1999. As you may recall, the looming “Year 2000 problem” was on everyone’s mind at the time. Doomsayers predicted that our technologically over-dependent society would plunge into chaos as computers worldwide failed to correctly recognize the year 2000. The local Memphis paper even ran an article on a man who was stockpiling toilet paper and raising live chickens—just in case. As it turns out, the Y2K problem failed to produce even a decent disaster movie, let alone the societal meltdown some people had anticipated.

However, the Y2K problem did bring to the public’s mind the way two-digit years are handled by computers. Writing the year with only two digits will probably always be an accepted form of date notation. As a VB programmer, you should be aware of how to handle two-digit years. Consider, for example, the following representations of dates:

7/12/43 
430712 

When a user enters one of the preceding strings in a text box, how do you know what year they really mean? If your program deals with birthdays, obviously they mean 1943. However, if you are writing a program that processes bank loans or other future dates the user may mean 2043. As you already know, variables of type Date contain the year, which can be retrieved using the Year property or DatePart function. However, date values can also be stored in other types, such as an integer or string. The date conversion routine Convert.ToDateTime would convert the aforementioned year to 1943. (The default behavior is years from 00-30 are converted to the 2000s, 30-99 are converted to the 1900s. As we will see in a moment, this range can be changed using the Windows Control Panel.) Of course, if you represent the year using four digits then you can specify any year you want.

Another consideration is what happens if the user omits the year altogether. Visual Basic’s built-in date conversion routines add the current year if a year is not specified:

'The variable dtChristmas will contain the current year 
Dim dtChristmas As Date = Convert.ToDateTime("12/25") 
Debug.WriteLine(Format(dtChristmas, "MM/dd/yyyy")) 

However, this may not always be appropriate to your application. Microsoft Money, for example, is smart enough to know that at the end of the year I may be entering checks for the new or old year, so it does not automatically assume the current year.

There is a nice touch you can add to your program’s user interface that will help eliminate confusion over what date is actually entered. Simply add code to format the date when a user exits the field, adding slashes and the appropriate number of year digits. Listing 6.2 shows an example of this function.

Listing 6.2. CHECKDATE.ZIP—Converting Strings to Dates
Private Function CheckValidDateString(ByRef DateString As String) As Boolean 

  'If the user did not type slashes, make a guess based on the length 
  If InStr(DateString, "-") = 0 And InStr(DateString, "/") = 0 _ 
     And InStr(DateString, "") = 0 Then 

    If DateString.Length = 4 Then 
        DateString = DateString.Substring(0, 2) & "/" & DateString.Substring(2) 
    ElseIf (DateString.Length = 6 Or DateString.Length = 8) Then 
        DateString = DateString.Substring(0, 2) & "/" & _ 
        DateString.Substring(2, 2) & "/" & DateString.Substring(4) 
    End If 

  End If 

  'If you can convert the string to a date and format it, it is valid 
  Try 
    DateString = Format(Convert.ToDateTime(DateString), "MM/dd/yyyy") 
    Return True 

  Catch e As Exception 
    Return False 

  End Try 

End Function 

To test the previous function, place it in your form class. Next, draw several text boxes on the form, and in their Leave events place lines of code similar to the following:

Dim s As String = TextBox1.Text 
If CheckValidDateString(s) Then TextBox1.Text = s 

Run the program, and enter some dates using two-digit years, dashes instead of slashes, or just numbers with no slashes. As you tab from one text box to the next the date will be reformatted appropriately, providing a nice visual confirmation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.154.86