--============================================================================= --| --| PACKAGE NAME: timekeeper --| --| NOTES: None. --| --============================================================================= WITH other_io; WITH text_io; PACKAGE BODY timekeeper IS -- Ranges for valid numbers of hours and minutes SUBTYPE hour_number IS natural RANGE 0 .. 23; SUBTYPE minute_number IS natural RANGE 0 .. 59; -- Constants in seconds seconds : CONSTANT duration := 1.0; one_day : CONSTANT duration := 86_400*seconds; one_hour : CONSTANT duration := 3_600*seconds; one_minute : CONSTANT duration := 60*seconds; -- Starting time for timer. time_0 : time := uninitialized_time; --========================================================================== --| --| PROCEDURE NAME: timekeeper.start_time --| --| ALGORITHM/STRATEGY: Get time from calendar.clock. --| --| NOTES: None. --| --========================================================================== PROCEDURE start_time (t : OUT time) IS BEGIN -- start_time -- Reset timer to begin at current time and return time to caller. time_0 := calendar.clock; t := time_0; END start_time; --========================================================================== --| --| PROCEDURE NAME: timekeeper.time_stamp --| --| ALGORITHM/STRATEGY: Procedure calendar.split used to separate time --| to be displayed into month, day, year, and seconds. Seconds broken --| down into hours, minutes, and seconds by repeated subtraction. --| --| NOTES: Two spaces are used for printing hours, minutes, and seconds, --| even if only a one-digit number is required. Seconds are printed to --| two decimal places. --| --========================================================================== PROCEDURE time_stamp (t : IN time := uninitialized_time) IS -- Type to facilitate printing of months TYPE month_name IS (anuary, ebruary, arch, pril, ay, une, uly, ugust, eptember, ctober, ovember, ecember); -- Initial characters of months. Needed because initial capitals -- are desired with other letters in month names lowercase. month_initial_char : ARRAY (0 .. 11) OF character := ('J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'); -- Package for month_name I/O PACKAGE month_io IS NEW text_io.enumeration_io (month_name); -- Time to be printed stamp_time : time; -- Component values of time to be printed year : calendar.year_number; month : calendar.month_number; day : calendar.day_number; hours : hour_number; minutes : minute_number; seconds : calendar.day_duration; BEGIN -- time_stamp -- Determine if time t or current time is to be printed IF (t = uninitialized_time) THEN stamp_time := calendar.clock; ELSE stamp_time := t; END IF; -- Break time to be printed into components calendar.split (stamp_time, year, month, day, seconds); -- Output month month := month - 1; text_io.put (month_initial_char(month)); month_io.put(month_name'val(month), set => text_io.lower_case); text_io.put (" "); -- Output day, year, " at " other_io.integer_io.put(day, width => 1); text_io.put (", "); other_io.integer_io.put(year, width => 4); text_io.put (" at "); -- Calculate and output number of hours hours := 0; WHILE (seconds >= one_hour) LOOP seconds := seconds - one_hour; hours := hours + 1; END LOOP; other_io.integer_io.put (hours, width => 2); text_io.put (":"); -- Calculate and output number of minutes minutes := 0; WHILE (seconds >= one_minute) LOOP seconds := seconds - one_minute; minutes := minutes + 1; END LOOP; other_io.integer_io.put (minutes, width => 2); text_io.put (":"); -- Output number of seconds other_io.duration_io.put (seconds, fore => 2, aft => 2); END time_stamp; --========================================================================== --| --| PROCEDURE NAME: timekeeper.get_time --| --| ALGORITHM/STRATEGY: Time returned from calendar.clock. --| --| NOTES: None. --| --========================================================================== PROCEDURE get_time (t : OUT time) IS BEGIN -- get_time t := calendar.clock; END get_time; --========================================================================== --| --| PROCEDURE NAME: timekeeper.print_elapsed_time --| --| ALGORITHM/STRATEGY: Parameter elapsed_in is assigned to elapsed, and --| number of days, etc., determined through repeated subtraction. --| --| NOTES: Tests are made to assure grammatical output ("1 hour," not --| "1 hours," etc.). --| --========================================================================== PROCEDURE print_elapsed_time (elapsed_in : IN duration) IS -- Seconds of elapsed_in yet to be accounted for in terms of days, etc. elapsed : duration; -- Number of days, hours, minutes, and seconds so far found -- in interval elapsed_in days : natural := 0; hours : hour_number := 0; minutes : minute_number := 0; seconds : calendar.day_duration; BEGIN -- print_elapsed_time -- Save interval to be printed in elapsed elapsed := elapsed_in; -- Compute number of days in interval WHILE (elapsed >= one_day) LOOP elapsed := elapsed - one_day; days := days + 1; END LOOP; -- Compute number of hours in interval WHILE (elapsed >= one_hour) LOOP elapsed := elapsed - one_hour; hours := hours + 1; END LOOP; -- Compute number of minutes in interval WHILE (elapsed >= one_minute) LOOP elapsed := elapsed - one_minute; minutes := minutes + 1; END LOOP; -- Output number of days, if any IF (days > 0) THEN other_io.integer_io.put (days, width => 1); IF (days = 1) THEN text_io.put (" day, "); ELSE text_io.put (" days, "); END IF; END IF; -- Output number of hours, if any IF (days > 0) OR ELSE (hours > 0) THEN other_io.integer_io.put (hours, width => 1); IF (hours = 1) THEN text_io.put (" hour, "); ELSE text_io.put (" hours, "); END IF; END IF; -- Output number of minutes, if any IF (days > 0) OR ELSE (hours > 0) OR ELSE (minutes > 0) THEN other_io.integer_io.put (minutes, width => 1); IF (minutes = 1) THEN text_io.put (" minute, "); ELSE text_io.put (" minutes, "); END IF; END IF; -- Output number of seconds other_io.duration_io.put (elapsed, fore => 2, aft => 1); text_io.put (" seconds"); END print_elapsed_time; --========================================================================== --| --| PROCEDURE NAME: timekeeper.elapsed_time --| --| ALGORITHM/STRATEGY: Call print_elapsed_time to output length of --| appropriate interval. --| --| NOTES: None. --| --========================================================================== PROCEDURE elapsed_time (t : IN time := uninitialized_time) IS BEGIN -- elapsed_time -- Output length of interval from from time_0 to current time or -- to time t IF (t = uninitialized_time) THEN print_elapsed_time (calendar.clock - time_0); ELSE print_elapsed_time (t - time_0); END IF; END elapsed_time; END timekeeper;