## Visual Basic in 12 Easy Lessons vel14.htm

- What You'll Learn
- Getting the Date and Time
- Set the Date and Time From Visual Basic
- How Much Time Has Passed?
- Serial Dates and Times
- Formatting with Format()
- Homework
  - General Knowledge
  - Find the Bug
  - Extra Credit

#
Lesson 7, Unit 14

##
Working with Dates, Times, and Formats

###
What You'll Learn

- Getting the date and time
- Setting the date and time from Visual Basic
- Determining how much time has passed
- Using date arithmetic
- Getting serial dates and times

This unit completes your learning of Visual Basic's built-in functions by exploring the built-in date, time, and formatting functions. This is the first unit of the book in which you'll work directly with the variant data type even though you've seen references to Variant throughout the book.

In addition to the functions, this unit discusses the several date and time statements that augment the work you'll do with date and time function values. Date and time values are critical for time keeping, transaction recording, and reporting, so you must be able to write programs that track and work with such values. Visual Basic supports one of the most comprehensive library of date and time functions, as you'll see in this unit.

> > Note: The most important part of learning many of the date and time values is learning how Visual Basic stores date and time values in memory.

The formatting power of Visual Basic is superb as well. You'll see the formatting tables that convert your program output to any format needed. Visual Basic supports date, time, string, and number formatting capabilities.

###
Getting the Date and Time

Concept: The Now(), Date$() and Time$() functions (and their cousins, the Date() and Time() functions) look inside your computer's clock and calendar to retrieve the current date and time for your program's use.

In ancient times (a little over eight years ago), computers couldn't remember the date and time if you turned them off. They've come a long way! Somebody thought of the brilliant idea of putting a battery inside the computer so that the computer would remember the date and time every time you powered on the machine. Of course, batteries had been in wrist watches for years before then, but computer makers were so busy trying to squeeze 360K of storage onto one of those little 5 1/4-inch floppy disks that they didn't get around to the battery for a while.

Visual Basic gives your Windows programs access to the date and time values stored internally in your computer. Assuming that the date and time are set properly, you can assign the date and time function return values to variables or display those values in controls.

> > Definition: 24-hour time measures time from 0 to 24 hours.

Some of the time values returned from these functions return a 24-hour time. If you're used to expressing time values using a 12-hour a.m. or p.m. time, you'll have to get accustomed to the 24-hour time in which Visual Basic adds 12 to all time values after 12:59 PM. Therefore, 3:45 in the morning is 3:45, but 3:45 in the afternoon is 15:45.

> > Note: You can use the Format() function to change any 24-hour time to a 12-hour clock using the AM and PM indicators if you want to.

The Now(), Date$(), Date(), Time$(), and Time() functions are functions that don't accept arguments. As such, Visual Basic removes the parentheses if you type them after these functions. Nevertheless, this book does use the parentheses after the functions to remind you that they are built-in functions.

The Now() function returns both the date and time. Now() returns a Variant data type in the following format:

    mm/dd/yy hh:mm:ss [AM][PM]

where mm is a 2-digit month, dd is a 2-digit day, and yy is a 2-digit year value. The time appears to the right of the date. The time section of Now()'s return value uses a 12-hour clock rather than the 24-hour clock used by Time$() and Time(). hh is a 2-digit hour, mm is a 2-digit minute value, and ss is a 2-digit second value. Just for your information, Visual Basic stores this complete value internally as a double-precision value because only the double-precision value is large enough to hold that much information. Even though Visual Basic stores the date and time internally in a double-precision value, Now() returns the value formatted as shown inside the variant data type.

If you've set your computer's version of Windows to an international setting that requires a different date and time format, these functions return date and time values that match your country's setting.

Date$() returns the system date string in the following format:

    mm-dd-yyyy

Date() returns the value in the variant data type. The difference between Date() and Date$() is that Date() doesn't return leading zeros in day or month numbers less than 10, Date() doesn't append 19 to the year, and Date() inserts forward slashes instead of hyphens between the date values.

> > Tip: Given the closeness to the year 2000, use Date$() exclusively so that the full year is returned in case you still use your program when the century turns.

Time$() returns the system time in a string data type in the following 24-hour format:

    hh:mm:ss

where hh is the hour (from 00 to 23), mm is the minute (from 00 to 59), and ss is the second (from 00 to 59). Time() returns the system time in a variant data type in the following 12-hour format:

    hh:mm:ss [AM] [PM]

where Time$() always returns either AM or PM after the time to indicate the time of day.

Stop and Type: Listing 14.1 contains several assignment statements whose remarks describe the date or time value returned from the functions.

Review: The date and time functions return values set inside your computer so that you can use and display those values in your program. The function that you use, Now(), Date(), or Time() (or the Date$() and Time$() counterparts) return various date and time formats.

Listing 14.1. Accessing time and date values.

    1: lblNow.Caption = Now() ' 7/9/97 07:48 PM

    2: lblDate1.Caption = Date() ' 7/9/97

    3: lblDate2.Caption = Date$() ' 07/09/1997

    4: lblTime1.Caption = Time() ' 07:48:24 PM

    5: lblTime2.Caption = Time$() ' 19:48:24

Analysis: The assignment statements assume that the current date and time is July 9, 1997 at 7:48:24 in the evening. The different formats offer you the choice of how you want the date and time values displayed in the target labels.

###
Set the Date and Time From Visual Basic

Concept: The Date and Time statements (not the functions) enable you to change the computer's date and time values from within a Visual Basic application. The date and time values remain set until you change them again, either through subsequent Date and Time statements or through DOS or Windows commands.

The DOS DATE and TIME commands enable you to check and set your computer's date and time settings. The Windows Control Panel program inside the Main program group also enables you to set these values from within Windows. Be sure to check your computer's date and time every month or so to make sure they're accurate.

Visual Basic includes the Date and Time statements that set the date and time values of your computer's clock and calendar. Be sure to keep the parentheses off the Date and Time statements, or Visual Basic will think that you're improperly using the corresponding functions.

Here are the formats of the Date and Time statements:

    Date[$] = dateExpression

and

    Time[$] = timeExpression

As with the corresponding functions, there are two versions of each statement, and the dollar sign distinguishes between the versions. If you don't specify the trailing dollar sign, you must enter the dateExpression as an unambiguous date value, and the dateExpression must be a string or date data type. All of the following set the computer's current date to July 9, 1998:

    Date = 7/9/1997

    Date = 07/9/97

    Date = July 9, 1997

    Date = Jul 9, 1997

    Date = 9-Jul-1997

    Date = 9 July 1997

    Date = 9 July 97

The dateExpression must contain a valid date between January 1, 1980 and December 31, 2099, or Visual Basic generates an error.

If you do specify the trailing dollar sign (as in Date$), you can enter the dateExpression only in the following formats:

    Date$ = 07-9-97

    Date$ = 7-9-1998

    Date$ = 7/9/97

    Date$ = 7/9/1997

Owing to the many date formats, Visual Basic recognizes just about any way that you're used to specifying the date.

If you don't specify the trailing dollar sign, you can enter the timeExpression as either a 12-hour clock or a 24-hour clock with quotation marks, as follows:

    Time = "7:48 PM"

or

    Time = "19:48"

If you do specify the trailing dollar sign (as in Time$), you can enter the timeExpression in any of these formats:

    hh

    hh:mm

    hh:mm:ss

You must use a 24-hour clock value when using Time$.

> > Tip: Using these Time$ formats, you change only what you want to change. If your time zone has just turned to daylight savings time, for example, you can change just the hour.

Stop and Type: Listing 14.2 contains a section of code that enables the user to change both the date and time.

Review: The Date, Date$, Time, and Time$ statements enable you to change the computer's internal date and time settings. Those settings remain in effect until you or the user changes them again.

Listing 14.2. Letting the user change the date and time.

    1: Dim newDate As Variant

    2: Dim newTime As Variant

    3: MsgBox "The
    current date is " & Date$ ' Calls function

    4: newDate = InputBox("What do you want to set the date to?")

    5: If IsDate(newDate) Then

    6: Date$ = newDate

    7: End If ' Don't do anything if a good date isn't entered

    8: MsgBox "The
    date is now " & Date$

    9: MsgBox "The current time is " & Time$ ' Calls function

    10: newTime = InputBox("What do you want to set the time to?")

    11: If IsDate(newTime) Then

    12: Time$ = newTime

    13: End If ' Don't do
    anything if a good time isn't entered

    14: MsgBox "The time is now " & Time$

Analysis: After defining two variant variables in lines 1 and 2 to hold the date and time values entered by the user, the program displays the date in line 3 and asks the user to change the date in line 4. Line 5 uses the IsDate() function, which you learned about in the previous unit, to check that the user entered a proper date value. If the user didn't enter a valid date, the program skips line 6 and displays the current set date without change in line 8.

> > Note: Visual Basic won't allow any invalid date to slip through. If the user were to enter 2-30-96, the IsDate() function in line 5 would know that February doesn't have 30 days and would not consider the date to be valid.

Lines 9 through 14 perform the same routine for the time.

###
How Much Time Has Passed?

Concept: Visual Basic includes a Timer() function that enables you to compute the elapsed time between two time periods. Using Timer(), you can find out how many seconds have elapsed since midnight.

The Timer() function returns the number of seconds that have elapsed since your computer's clock was last midnight. Timer() requires no arguments; hence, Visual Basic removes Timer()'s parentheses if you type them, but this book uses the parentheses, as is the standard, to remind you that Timer() is a function and not a command.

Assuming that it's 11:40 p.m., the following statement stores 85206.9 in the variable named TMid:

    TMid = Timer()

Timer() returns a single-precision value. If you divide 85206.9 by 60, you'll get the number of minutes since midnight, and if you divide by another 60, you'll get the number of hours (a few less than 24) since midnight.

> > Warning: The Timer() function differs greatly from the timer control on the toolbox that you'll learn about in Lesson 10, "Making Programs Real World."

How can determining the number of seconds since midnight help you as a Visual Basic programmer? Timer() is perfect for timing an event. Suppose that you want to ask the user a question and determine how long it takes the user to answer. First, save the value of Timer() before you ask the user; then, subtract that value from the value of Timer after he or she answers. The difference of the two Timer() values is the number of seconds that the user took to answer.

Stop and Type: Listing 14.3 contains code that asks the user for a math answer and times how long the user takes to respond.

Review: The moment that your program executes the Timer() function, Visual Basic checks the computer's internal clock and returns the number of seconds since midnight.

Listing 14.3. Test the user's math speed.

    1: Dim Before, After, timeDiff As Variant

    2: Dim mathAns As String

    3:
    Before = Timer ' Save the time before asking

    4: Do

    5: mathAns = InputBox("What is 150 + 235?", "Hurry!")

    6: Loop Until Val(mathAns) = 285

    7: After = Timer ' Save the time after answering

    8: ' The difference between the time values

    9: ' is how many seconds the user took to answer

    10: timeDiff = After - Before

    11: MsgBox "That took you only" + Str$(timeDiff) & " seconds!"

Output: Figure 14.1 shows the input box that asks the user for the answer.

Figure 14.1. Test the user's math ability!

Analysis: Line 3 saves the Timer() setting right before the input box that requests the user's answer appears. The Do loop in lines 4 through 6 then keeps asking the user for the answer until the user enters the appropriate response of 285. As soon as the user enters the correct response, line 7 stores the Timer() value at that point. Line 10 then computes the difference of the two values to determine the number of seconds that the response took.

###
Serial Dates and Times

Concept: Visual Basic supports the storage of serial date and time values. A serial value is a number stored as a VarType 7 (the Date data type, as you learned in the previous unit). The serial number allows you to break up dates into their day, month, and year values and allows you to break up times into their hour, minute, and second values.

> > Definition: A byte is one character of memory.

All the date and time functions that you've seen in this unit have been working with serial values. A serial value is the internal representation of a date or time, stored in a VarType 7 or a Variant data type. Visual Basic actually stores these values as double-precision values to ensure the full storage of time and date so that accurate date arithmetic can be performed. Visual Basic uses eight bytes memory of storage for double-precision values, which is enough room to hold the combined time and date value.

The following functions are explained in this section:

- DateSerial()
- DateValue()
- TimeSerial()
- TimeValue()
- Day()
- Month()
- Year()

All of these functions convert their arguments to serial date values. You then can use those serial date values to manage and modify specific parts of date and time values. Here is the format of the DateSerial() function:

    DateSerial(Year, Month, Day)

where Year is an integer year number (either 00 to 99 for 1900 to 1999, or a four-digit year number) or expression, Month is an integer month number (1 to 12) or expression, and Day is an integer day number (1 to 31) or expression. If you include an expression for any of the integer arguments, you specify the number of years, months, or days from or since a value.

These two DateSerial() function calls return the same value:

    d =
    DateSerial(1990, 10, 6)

and

    d = DateSerial(1980+10, 12-2, 1+5)

The DateSerial() function ensures that your date arguments don't go out of bounds. For example, 1992 was a leap year, so February of 1992 had 29 days. However, the following DateSerial() function call appears to produce an invalid date because February, even in leap years, can't have 30 days:

    d = DateSerial(1992, 2,
    29+1)

Nothing is wrong with this function call because DateSerial() adjusts the date evaluated so that d holds March 1, 1992, one day following the last day of February.

The DateValue() function is similar to DateSerial() except that the DateValue() function accepts a string argument, as the following format shows:

    DateValue(stringDateExpression)

The stringDateExpression must be a string that Visual Basic recognizes as a date (such as those for the Date$ statement described earlier in this chapter and valid dates entered by the user). If you ask the user to enter a date one date part value at a time (asking for the year, then the month, and then the day separately), you can use DateSerial() to convert those values to an internal serial date. If you ask the user to enter a full date (that you capture into a string variable) such as July 16, 1996, DateSerial() converts that string to the internal serial format needed for dates.

The TimeSerial() and TimeValue() functions work the same as their DateSerial() and DateValue() counterparts. If you have three individual values for a time of day, TimeSerial() converts those values to an internal time format (the Variant or VarType 7). Here is the format of TimeSerial():

    TimeSerial(Hour, Minute, Second)

The TimeSerial() function accepts expressions for any of its arguments and adjusts those expressions as needed, just as the DateSerial() function does.

If you have a string with a time value (maybe the user entered the time), the TimeValue() function converts that string to a time value with this format:

    TimeValue(stringTimeExpression)

The Day(), Month(), and Year() functions convert their date arguments (of Variant or the VarType 7 data type) to a day number, month number, or year number. These three functions are simple. Here are their formats:

    Day(DateArgument)

    Month(DateArgument)

    Year(DateArgument)

You often pass today's date (found with Now()) to the Day(), Month(), and Year() functions as shown here:

    d = Day(Now())

    m = Month(Now())

    y = Year(Now())

The current date's day of week number, month number, and year are stored in the three variables d, m, and y, respectively.

Stop and Type: Listing 14.4 contains a short section of code that asks the user for a date, uses the IsDate() function to ensure that the date is proper, and then uses the Month(), Day(), and Year() functions described here to break the date into its individual parts.

Review: The serial date value that Visual Basic uses for all date and time values enable you to use various functions to break apart and piece back together various date and time combinations.

Listing 14.4. Working with serial date values.

    1: Dim UserDate As Variant

    2: Dim DStr As String

    3:

    4: ' Ask the user for a
    date

    5: Do

    6: UserDate = InputBox("What's the date?")

    7: Loop While Not IsDate(UserDate)

    8:

    9: DStr = "Month: " & Month(UserDate)

    10: DStr = DStr + ", Day: " & Day(UserDate)

    11: DStr = DStr + ", Year:
    " & Year(UserDate)

    12:

    13: ' Display the date broken down

    14: MsgBox DStr

Output: Assuming that the user types 1/2/98 for the date in response to this code's InputBox() function call, Figure 14.2 contains the message box that shows the various parts of the dates.

Figure 14.2. Through functions, you can break up a date.

Review: Lines 1 and 2 define two variables needed by the rest of the program. The variant UserDate variable will hold a date value entered by the user, and the DStr variable will hold a message box string.

Lines 5 though 7 loop until the user enters an appropriate date value. The loop continues as long as IsDate() reveals that the user's date value is invalid. The loop quits asking the user for a date when line 7 determines that the date is valid.

Lines 9 through 11 build a fairly complicated string displayed by line 14's message box function. The lines concatenate several strings together, building upon the DStr variable. The Month(), Day(), and Year() functions all pick off the month, day, and year values from the date entered by the user to display the different values inside the message box, as shown in Figure 14.2.

###
Formatting with Format()

> > Definition: A logical value is the result of a relation or a True or False control value.

Concept: The Format() function formats numeric and logical values so that you can display that data in the exact format that you require. Until this section, you couldn't ensure that currency values displayed to two decimal places, but Format() enables you to format currency and all other numbers the way you need.

Visual Basic can't read your mind, so it doesn't know how you want numbers displayed in your applications. Although Visual Basic sometimes displays none, one, or two decimal places for currency values, you'll almost always want those currency values displayed to two decimal places.

> > Note: As with the date and time functions, if you've set your computer's international settings to a country other than the U.S.'s (as done for this book), your formatted currency values may differ from those shown here. Some countries swap the use of commas and decimal places from those used in the U.S.

The two Format() functions are Format$() and Format() and they differ only in their return data types. Format$() returns a string and Format() returns a variant data type. Here is the format of Format():

    Format$(Expression, FormatStr)

Often, you'll assign the result of the Format$() function to other variables and controls. Generally, you'll perform all needed calculations on numeric values before formatting those values. After you've performed the final calculations, you'll then format the values to string (or variant) data types and display the resulting answers as needed.

The Expression can be a variable, expression, or constant. The FormatStr must be a value from Table 14.1.

> > Note: Visual Basic contains many format strings in addition to the ones shown in Table 14.1. You can even develop your own programmer-defined format strings, although this book doesn't go into those.

> > Definition: A thousands separator is a decimal point or comma inside numbers over 999.

Table 14.1. The fixed FormatStr values.

FormatStr | Description
"Currency" | Ensures that a dollar sign, $, appears before the formatted value followed by a thousands separator (the country setting determines whether the thousands separator is a comma or a decimal), and that two decimal places show. Visual Basic displays negative values in parentheses.
"Fixed" | Displays at least one digit before and two digits following the decimal point with no thousands separator.
"General Number" | Displays the number with no thousands separator.
"Medium Time" | Displays the time in 12-hour format and the AM or PM indicator.
"On/Off" | Displays On if the value contains a nonzero or True value and displays Off if the value contains zero or a False value. These values correspond to a special internal representation of computer values called binary numbers.
"Percent" | Displays the number, multiplied by 100, and adds the percent sign to the right of the number.
"Scientific" | Displays numbers in scientific notation.
"Short Time" | Displays the time in 24-hour format.
"True/False" | Displays True if the value contains a nonzero or True value, and displays False if the value contains zero or a False value.
"Yes/No" | Displays Yes if the value contains a nonzero or True value, and displays No if the value contains zero or a False value.

> > You'll Rarely Need Format Codes: If the predefined formats from Table 14.1 don't match the format you need, you can define your own using special formatting codes. This unit would be at least twice as long as it is if all the programmer-defined formats were shown here. The good news is that, when you do define your own formats, you'll almost always use just a combination of the pound sign and zeros to format the values you need.
> > Each pound sign in the format indicates where a digit goes, and the zero indicates that you want either leading or trailing zeros. The following assignment displays the value of Weight to three decimal places:
> > lblMeas.Caption = Format$(Weight, "######.000")
> > You could also request that no decimal point should appear by formatting a fractional value such as Weight, and Visual Basic will round the number as needed to fit the target format. The following assignment displays Weight with no decimal places shown on the screen:
> > lblMeas.Caption = Format$(Weight, "######")

Stop and Type: Listing 14.5 contains a series of formatting function calls that convert numeric and logical values to formatted variant data types that you can display.

Review: There are two formatting functions. Format$() returns a string and Format() returns a variant value. The Format$() function formats values so that the values look the way you want them to look. The predefined format strings make it easy to display numbers and logical values in the format that you require.

Listing 14.5. Formatting numeric and logical values.

    1: Dim FormValue As String

    2:

    3: ' Change 12345.678 to $12,345.68

    4: FormValue1 = Format$(12345.678, "Currency")

    5:

    6: ' Change 12345678 to 12345.68

    7:
    FormValue2 = Format$(12345.678, "Fixes")

    8:

    9: ' Change .52 to 52.00%

    10: FormValue3 = Format$(.52, "Percent")

    11:

    12: ' Change 1 to Yes

    13: FormValue4 = Format$(1, "Yes/No")

    14:

    15: ' Change 0 to No

    16: FormValue5 =
    Format$(0, "Yes/No")

    17:

    18: ' Change 1 to True

    19: FormValue6 = Format$(1, "True/False")

    20:

    21: ' Change 0 to False

    22: FormValue7 = Format$(0, "True/False")

Analysis: Line 4 converts the decimal single-precision number to a formatted currency string. If you were to display FormValue1 in a label's caption, the caption would show $12,345.68. Line 7 formats the same number for a noncurrency value with two decimal places. Line 10 changes a fractional number to its corresponding decimal percentage value and adds the percent sign after the formatted percent to show the percentage format. Line 13 changes the nonzero value of 1 to Yes. You can format any nonzero or relational result to a Yes, No, True, or False value, as shown in the program's remaining lines, so the values appear exactly the way you want them to look.

###
Homework

####
General Knowledge

1. True or false: Now() returns information for both the current date and time.
2. Where do the time and date functions get their values?
3. What is the difference between 12-hour time and 24-hour time?
4. True or false: 9:23 can be either 12-hour or 24-hour time.
5. True or false: 9:23 a.m. can be either 12-hour or 24-hour time.
6. What is the 24-hour time value for 7:54 a.m.?
7. What is the difference between the Date$() and Date() functions?
8. True or false: Visual Basic supports both a Now() and a Now$() function.
9. Does Now() return its time value using a 12-hour or 24-hour clock?
10. True or false: The time and date functions ignore your international time and date settings.
11. True or false: Date() and Time() set your computer's date and time.
12. Which function, Date() or Date$(), should you use if you think that your computer program will still be in use in the year 2000?
13. Describe the purpose of the Timer() function.
14. What is a byte?
15. What data type does a serial date value require?
16. How does the TimeValue() function relate to the Hour(), Minute(), and Second() functions?
17. What is a logical value?
18. What functions format numeric output for you?
19. What is the difference between Format() and Format$()?
20. What is a thousands separator?
21. What is the difference between the "Fixed" and "Currency" fixed-format strings?

####
Find the Bug

1. Consider the user's input shown in Figure 14.3. The program is setting a time with this input box request:
2. Time$ = InputBox("What do you want to set the time to?")
3. Why do you suppose that Visual Basic indicates (as soon as the user presses OK in the input box) that an error occurred?

Figure 14.3. Something's going to be wrong here.

####
Extra Credit

Write code that asks the user for the time that she or he clocked into work and then asks for the time that she or he clocked out. Display in three labels the total amount of seconds worked, the total number of minutes worked, and the total number of hours worked.