BillSoo
08-08-2002, 01:25 PM
As VB programmers, we have access to a wide range of functions to measure time. There are so many in fact, that at times it can be difficult to determine which one to use. Here is a brief tutorial on using some common functions.
Macro Time (time intervals of 1 second or larger)
A common question is what is the date or time right now? To answer that, VB has 3 functions available. The Date function returns the current date, the Time function returns the current time and the Now function returns the current time and date.
Actually, all three return time/date because all three return a variable of type Date. In previous versions of VB, there was no Date type. Instead, the functions returned a Double. Today, you can still treat the Date Type as if it were a double.
The Date type is an 8 byte double precision floating point number representing the number of days since midnight, Dec 30, 1899. The fractional part of the date represents the time in days. So 12 noon would be half a day, or 0.5.
For instance if the time/date now were Aug 8, 2002 6:00 PM, the values of the three functions would be:
Now() = 37476.75
Date() = 37476
Time() = 0.75
There are a number of functions like DateAdd or DateDiff that return a date after adding or subtracting other dates. Well, in some cases, you can do that directly. For instance, instead of
t = DateAdd("d",7,Now()) 'add one week to current date/time
you could simply say
t = Now() + 7 'add one week to current date/time
Similarily, you can add/subtract time if you keep in mind that time is in fractional days. There are 24 hrs in a day, 1440 minutes in a day and 86400 seconds in a day so to add, say, 10 seconds to a current time, you would use:
t = Now() + 10/86400 'convert 10 seconds to days
Other functions you might use are time conversion functions like Hour, Minute, Day, WeekDay, Month or Year. These functions all return the specified portion of the supplied date. eg. Year(now()) would return the current year (2002).
There is also the Format function, with support for various kinds of date formats, but that is somewhat outside the bounds of this tutorial.
Micro Time (time intervals less than 1 second)
The other end of the spectrum is measuring very fast events and there are a number of ways to do that.
Most newbies start by using the Timer control. This control repeatedly fires an event after a set number of milliseconds. However, despite the seemingly high resolution, the actual resolution is typically much worse than a millisecond. The Timer control sets it's time by the internal tick counter. On Win9x and lower machines, this counter fires around 18 times per second, so the resolution is about 55 ms. On Win2K and up, the tick counter fires faster so the resolution is a finer 10 ms or so.
Similarily, the Timer function, which returns the number of seconds since midnight, also uses the tick count internally, so it's resolution is about 55 (or 10) ms as well.
Higher resolution requires API calls. So let's take a look at some of the variety available.
GetTickCount - ms since system booted. Restricted to resolution of Tick counter
Sleep - halts app for specified number of ms
timeGetTime - returns system time in ms
QueryPerformanceCounter - returns current high performance count value
QueryPerformanceFrequency - returns number of counts per second
GetTickCount has the same resolution problems as Timer() and the timer control. But it may have less overhead so it could be useful.
Sleep has high resolution, but it will freeze your app while it waits. You have a bit more versatility with TimeGetTime or the other functions.
timeGetTime is OS dependant. On Win9x systems, its resolution is 1ms. On WinNT and higher, it's resolution is adjustable by using the timeBeginPeriod and timeEndPeriod API functions. Default resolution on NT is probably around 10ms.
QueryPerformanceCounter is also system dependant in that faster CPUs will cycle the counter faster than slow CPUs. That's why we need QueryPerformanceFrequency to determine the actual frequency for a particular system.
Some old systems do not support a high performance frequency counter. Some REALLY old systems do not support multimedia at all. So in theory, use QueryPerformanceCounter unless it isn't supported, in which case you can use timeGetTime, unless it isn't supported in which case you can use GetTickCount.
Oddball Time systems
There are a number of other time formats supported by windows. One is SystemTime and another is FileTime. SystemTime is a large structure that contains individual elements for day, year, month, hour, millisecond etc. FileTime is another structure that contains the number of 100 nano second periods since Jan 1, 1601. It is unlikely that will have to use these structures, but if you do, use MSDN.
Macro Time (time intervals of 1 second or larger)
A common question is what is the date or time right now? To answer that, VB has 3 functions available. The Date function returns the current date, the Time function returns the current time and the Now function returns the current time and date.
Actually, all three return time/date because all three return a variable of type Date. In previous versions of VB, there was no Date type. Instead, the functions returned a Double. Today, you can still treat the Date Type as if it were a double.
The Date type is an 8 byte double precision floating point number representing the number of days since midnight, Dec 30, 1899. The fractional part of the date represents the time in days. So 12 noon would be half a day, or 0.5.
For instance if the time/date now were Aug 8, 2002 6:00 PM, the values of the three functions would be:
Now() = 37476.75
Date() = 37476
Time() = 0.75
There are a number of functions like DateAdd or DateDiff that return a date after adding or subtracting other dates. Well, in some cases, you can do that directly. For instance, instead of
t = DateAdd("d",7,Now()) 'add one week to current date/time
you could simply say
t = Now() + 7 'add one week to current date/time
Similarily, you can add/subtract time if you keep in mind that time is in fractional days. There are 24 hrs in a day, 1440 minutes in a day and 86400 seconds in a day so to add, say, 10 seconds to a current time, you would use:
t = Now() + 10/86400 'convert 10 seconds to days
Other functions you might use are time conversion functions like Hour, Minute, Day, WeekDay, Month or Year. These functions all return the specified portion of the supplied date. eg. Year(now()) would return the current year (2002).
There is also the Format function, with support for various kinds of date formats, but that is somewhat outside the bounds of this tutorial.
Micro Time (time intervals less than 1 second)
The other end of the spectrum is measuring very fast events and there are a number of ways to do that.
Most newbies start by using the Timer control. This control repeatedly fires an event after a set number of milliseconds. However, despite the seemingly high resolution, the actual resolution is typically much worse than a millisecond. The Timer control sets it's time by the internal tick counter. On Win9x and lower machines, this counter fires around 18 times per second, so the resolution is about 55 ms. On Win2K and up, the tick counter fires faster so the resolution is a finer 10 ms or so.
Similarily, the Timer function, which returns the number of seconds since midnight, also uses the tick count internally, so it's resolution is about 55 (or 10) ms as well.
Higher resolution requires API calls. So let's take a look at some of the variety available.
GetTickCount - ms since system booted. Restricted to resolution of Tick counter
Sleep - halts app for specified number of ms
timeGetTime - returns system time in ms
QueryPerformanceCounter - returns current high performance count value
QueryPerformanceFrequency - returns number of counts per second
GetTickCount has the same resolution problems as Timer() and the timer control. But it may have less overhead so it could be useful.
Sleep has high resolution, but it will freeze your app while it waits. You have a bit more versatility with TimeGetTime or the other functions.
timeGetTime is OS dependant. On Win9x systems, its resolution is 1ms. On WinNT and higher, it's resolution is adjustable by using the timeBeginPeriod and timeEndPeriod API functions. Default resolution on NT is probably around 10ms.
QueryPerformanceCounter is also system dependant in that faster CPUs will cycle the counter faster than slow CPUs. That's why we need QueryPerformanceFrequency to determine the actual frequency for a particular system.
Some old systems do not support a high performance frequency counter. Some REALLY old systems do not support multimedia at all. So in theory, use QueryPerformanceCounter unless it isn't supported, in which case you can use timeGetTime, unless it isn't supported in which case you can use GetTickCount.
Oddball Time systems
There are a number of other time formats supported by windows. One is SystemTime and another is FileTime. SystemTime is a large structure that contains individual elements for day, year, month, hour, millisecond etc. FileTime is another structure that contains the number of 100 nano second periods since Jan 1, 1601. It is unlikely that will have to use these structures, but if you do, use MSDN.