> ##

> ## 6.5 Times

> The HLA Standard Library provides a simple time module that lets you manipulate times in an HHMMSS (hours/minutes/seconds) format. The time namespace in the date/time module defines the time data type as follows:

>     type

>     	timerec:

>     		record

>     			secs:uns8;

>     			mins:uns8;

>     			hours:uns16;

>     		endrecord;

> This format easily handles 60 seconds per minute and 60 minutes per hour. It also handles up to 65,535 hours (just over 2730 days or about 7-1/2 years).

> The advantages to this time format parallel the advantages of the date format: it is easy to convert the time format to/from external representation (i.e., HH:MM:SS) and the storage format lets you compare times by treating them as uns32 objects. Another advantage to this format is that it supports more than 24 hours, so you can use it to maintain timings for events that are not calendar based (up to seven years).

> There are a couple of disadvantages to this format. The primary disadvantage is that the minimum granularity is one second; if you want to work with fractions of a second then you will need to use a different format and you will have to write the functions for that format. Another disadvantage is that time calculations are somewhat inconvenient. It is difficult to add n seconds to a time variable.

> Before discussing the HLA Standard Library Time functions, a quick discussion of other possible time formats is probably wise. The only reasonable alternative to the HH:MM:SS format that the HLA Standard Library Time module uses is to use an integer value to represent some number of time units. The only question is "what time units do you want to use?" Whatever time format you use, you should be able to represent at least 86,400 seconds (24 hours) with the format. Furthermore, the granularity should be one second or less. This effectively means you will need at least 32 bits since 16 bits only provides for 65,536 seconds at one second granularity (okay, 24 bits would work, but it's much easier to work with four-byte objects than three-byte objects).

> With 32-bits, we can easily represent more than 24 hours' worth of milliseconds (in fact, you can represent almost 50 days before the format rolls over). We could represent five days with a 1/10,000 second granularity, but this is not a common timing to use (most people want microseconds if they need better than millisecond granularity), so millisecond granularity is probably the best choice for a 32-bit format. If you need better than millisecond granularity, you should use a combined date/time 64-bit format that measures microseconds since Julian Day Number zero (Jan 1, 4713 BCE). That's good for about a half million years. If you need finer granularity than microseconds, well, you're own your own! You'll have to carefully weigh the issues of granularity vs. years covered vs. the size of your data.

> ### 6.5.1 time.curTime

> This function returns the current time as read from the system's time of day clock. The calling syntax for this function is the following:

>     time.curTime( timeRecVar );

> This function call stores the current system time in the time.timerec variable you pass as a parameter. On Windows systems, the current time is the wall clock time for your particular time zone; under Linux, the current time is always given in UTC (Universal Coordinated Time) and you must adjust according to your particular time zone to get the local time. Keep this difference in mind when porting programs between Windows and Linux.

> ### 6.5.2 time.hmsToSecs and time.secstoHMS

> These two functions convert between the HLA internal time format and a pure seconds format. Generally, when doing time arithmetic (e.g., time plus seconds, minutes, or hours), it's easiest to convert your times to seconds, do the calculations with seconds, and then translate the time back to the HLA internal format. This lets you avoid the headaches of modulo-60 arithmetic.

> The calling sequences for the time.hmsToSecs function are

>     time.hmsToSecs( timeRecValue );

>     time.hmsToSecs( h, m, s );

> Both functions return the number of seconds in the EAX register. They differ only in the type of parameters they expect. The first form above expects an HLA time.timerec value. The second call above lets you directly specify the hours, minutes, and seconds as separate parameters. The h parameter must be a word value, the m and s parameters must be byte values.

> The time.secsToHMS function uses the following calling sequence:

>     time.secsToHMS( seconds, timeRecVar );

> The first parameter must be an uns32 value specifying some number of seconds less than 235,939,600 seconds (which corresponds to 65,536 hours). The second parameter in this call must be a time.timerec variable. This function converts the seconds parameter to the HLA internal time format and stores the value into the timeRecVar variable.

> ### 6.5.3 Time Input/Output

> The HLA Standard Library doesn't provide any specific I/O routines for time data. However, reading and writing time data in ASCII form is a fairly trivial process. This section will provide some examples of time I/O using the HLA Standard Input and Standard Output modules.

> To output time in a standard HH:MM:SS format, just use the stdout.putisize routines with a width value of two and a fill character of `0' for the three fields of the HLA time.timerec data type. The following code demonstrates this:

>     static

>     	t:time.timerec;

>     		.

>     		.

>     		.

>     	stdout.putisize( t.h, 2, `0' );

>     	stdout.put( `:' );

>     	stdout.putisize( t.m, 2, `0' );

>     	stdout.put( `:' );

>     	stdout.putisize( t.s, 2, `0' );

> If this seems like too much typing, well fear not; in a later chapter you will learn how to create your own functions and you can put this code into a function that will print the time with a single function call.

> Time input is only a little more complicated. As it turns out, HLA accepts the colon (":") character as a delimiter when reading numbers from the user. Therefore, reading a time value is no more difficult than reading any other three integer values; you can do it with a single call like the following:

>     	stdin.get( t.hours, t.mins, t.secs );

> There is one remaining problem with the time input code: it does not validate the input. To do this, you must manually check the seconds and minutes fields to ensure they are values in the range 0..59. If you wish to enforce a limit on the hours field, you should check that value as well. The following code offers one possible solution:

>     	stdin.get( t.hours, t.mins, t.secs );

>     	if( t.m >= 60 ) then

>     		raise( ex.ValueOutOfRange );

>     	endif;

>     	if( t.s >= 60 ) then

>     		raise( ex.ValueOutOfRange );

>     	endif;

> ## 6.6 Putting It All Together

> Date and time data types do not get anywhere near the consideration they deserve in modern programs. To help ensure that you calculate dates properly in your HLA programs, the HLA Standard Library provides a set of date and time functions that ease the use of dates and times in your programs.