DOCUMENT #681 ======================================================================= CALCULATING ELAPSED TIME ======================================================================= Product: R:BASE Version : 3.1 & Higher ======================================================================= Area : PROGRAMMING Category: FUNCTIONS & EXPRESSIONS ======================================================================= Timing calculations are used for sporting events, scientific experiments, and also for determining the most efficient programming technique for an application. There are various ways to calculate elapsed time in R:BASE and these methods are outlined below. Programming Methods to Calculate Elapsed Time ============================================= The following method using the system variable, #TIME, calculates elapsed time for a procedure that occurs within a 24 hour period only. The final result is displayed in a 'TIME' format as follows: 03:30:40. *(TIMER.CMD) SET VAR vbegin TIME = .#time *(Enter the command(s) you are timing here) SET VAR vend TIME = .#time SET VAR vdiff INTEGER= (.vend-.vbegin) *(If the value of vdiff is negative, you have crossed) *(midnight and must add one day in 'seconds' to the value of) *(vdiff) SET VAR vsec INTEGER = (IFLT(.vdiff,0,(.vdiff + 86400),+ .vdiff)) *(The RTIME function converts the integer into a 'TIME') *(format) SET VAR vtime TIME = (RTIME(0,0,.vsec)) WRITE .vtime The following method uses both the system date, #DATE, and system time, #TIME, to calculate timings that occur either within a 24 hour period or that span days. The final result is displayed as follows: 25 hours, 59 minutes, and 50 seconds. These commands are placed at the beginning of the code or process you want to time: *(START.CMD) SET VAR vsec INTEGER, vmin INTEGER SET VAR vhrs INTEGER, vtime TEXT SET VAR vbegtime TIME = .#time, vbegday DATE = .#date The variables that hold elapsed hours (vhrs), minutes (vmin), and seconds (vsec) are all defined as integers so that the fractional portions won't show. If you want to see the fractions, define the variables with a DOUBLE data type. The following commands are placed at the end of the code or process that you are timing. *(STOP.CMD) SET VAR vendtime TIME = .#time, vendday DATE = .#date *(The value of the system date is verified to determine) *(how many days in seconds must be added ) *(to the timed process) SET VAR vsec = (IFEQ(.vendday,.vbegday, + (.vendtime - .vbegtime), (((.vendday - .vbegday) * + 86400) + (00:00:00 - .vbegtime) + (.vendtime - + 00:00:00)))) SET VAR vmin = (.vsec/60) SET VAR vsecleft = (MOD(.vsec,60)) SET VAR vhrs = (.vmin/60) SET VAR vminleft = (MOD(.vmin,60)) SET VAR vtime = ((CTXT(.vhrs)) & 'hours,' & + (CTXT(.vminleft)) & 'minutes, and' & (CTXT(.vsecleft)) + & 'seconds.') CLS WRITE .vtime Both START.CMD, and STOP.CMD work when timing a process that lasts several days. However, these programs use global variables that can be erased by a power interruption, a CLEAR ALL VAR command, or an exit from R:BASE. Timings Using Computed Columns ============================== For a more permanent timing process, use the following code to add a table named 'TIMES' to your database. These columns could be added to an existing table. CREATE TABLE times + (begtime TIME, + begday DATE, + endtime TIME, + endday DATE, + seconds = (IFEQ(endday, begday, (endtime - begtime), + (((endday - begday) * 86400) + (00:00:00 - begtime) ++ (endtime - 00:00:00)))) INTEGER, + minutes = (seconds/60) INTEGER, + secleft =(MOD(seconds,60)) INTEGER, + hours = (minutes/60) INTEGER, + minleft = (MOD(minutes,60)) INTEGER, + timing = ((CTXT(hours)) & 'hours,' & (CTXT(minleft)) + & 'minutes, and' & (CTXT(secleft)) & 'seconds.') + TEXT 40) Load some sample data into the four data columns (begday, begtime, endday, and endtime) by using the LOAD WITH PROMPTS command. Now you can see the timings by using the following command: SELECT timing FROM times. To add new rows for new timings, put this command at the beginning of the process you're timing: INSERT INTO times (begtime begday) VALUES (.#time .#date) Then put these two commands at the end of the process: UPDATE times SET endtime = .#time, endday = .#date WHERE + COUNT = LAST You can then use the same select command, SELECT timing FROM times, to see the calculated time for your procedure. You may also want to include a column in the table to name the procedure being timed. Timing Calculations in Reports ============================== If you don't want to add computed columns to your table, the same results can be obtained by putting the expressions into a report. Include the following columns in your table: begtime (TIME), begday (DATE), endtime (TIME), and endday (DATE). Define these expressions in your report: vsec INTEGER = (IFEQ(endday,begday,(endtime - begtime),+ (((endday - begday) * 86400) + (00:00:00 - begtime) ++ (endtime - 00:00:00)))) vmin INTEGER = (.vsec/60) vsecleft INTEGER = (MOD(.vsec,60)) vminleft INTEGER = (MOD(.vmin,60)) vhours INTEGER = (MOD(.vmin,60)) vtiming TEXT = ((CTXT(.vhours)) & 'hours,' &+ (CTXT(.vminleft)) & 'minutes, and' & (CTXT(.vsecleft))+ & 'seconds.') After defining the expressions, locate the variable vtiming in the desired position on your report.