9.6 Delay Statements, Duration, and Time
A 
delay_statement 
is used to block further execution until a specified 
expiration time 
is reached. The expiration time can be specified either as a particular 
point in time (in a 
delay_until_statement), 
or in seconds from the current time (in a 
delay_relative_statement). 
The language-defined package Calendar provides definitions for a type 
Time and associated operations, including a function Clock that returns 
the current time. 
 
Syntax
delay_until_statement ::= delay until delay_expression;
 
delay_relative_statement ::= delay delay_expression;
 
Name Resolution Rules
Legality Rules
There 
can be multiple time bases, each with a corresponding clock, and a corresponding 
time type. The type of the 
delay_expression 
in a 
delay_until_statement 
shall be a time type — either the type Time defined in the language-defined 
package Calendar (see below), the type Time in the package Real_Time 
(see 
D.8), or some other implementation-defined 
time type. 
 
Static Semantics
There is a predefined fixed point type named Duration, 
declared in the visible part of package Standard; a value of type Duration 
is used to represent the length of an interval of time, expressed in 
seconds. The type Duration is not specific to a particular time base, 
but can be used with any time base.
A value of the type Time in package Calendar, or 
of some other time type, represents a time as reported by a corresponding 
clock.
The following language-defined 
library package exists: 
package Ada.Calendar 
is
  type Time 
is private;
 
  subtype Year_Number  
is Integer 
range 1901 .. 2399;
  
subtype Month_Number 
is Integer 
range 1 .. 12;
  
subtype Day_Number   
is Integer 
range 1 .. 31;
  
subtype Day_Duration 
is Duration 
range 0.0 .. 86_400.0;
 
  function Clock 
return Time;
 
  function Year   (Date : Time) 
return Year_Number;
  
function Month  (Date : Time) 
return Month_Number;
  
function Day    (Date : Time) 
return Day_Number;
  
function Seconds(Date : Time) 
return Day_Duration;
 
  procedure Split (Date  : 
in Time;
                   Year    : 
out Year_Number;
                   Month   : 
out Month_Number;
                   Day     : 
out Day_Number;
                   Seconds : 
out Day_Duration);
 
  function Time_Of(Year  : Year_Number;
                   Month   : Month_Number;
                   Day     : Day_Number;
                   Seconds : Day_Duration := 0.0)
   
return Time;
 
  function "+" (Left : Time;   Right : Duration) return Time;
  function "+" (Left : Duration; Right : Time) return Time;
  function "-" (Left : Time;   Right : Duration) return Time;
  function "-" (Left : Time;   Right : Time) return Duration;
  function "<" (Left, Right : Time) return Boolean;
  function "<="(Left, Right : Time) return Boolean;
  function ">" (Left, Right : Time) return Boolean;
  function ">="(Left, Right : Time) return Boolean;
private
   ... -- not specified by the language
end Ada.Calendar;
Dynamic Semantics
For the execution of a 
delay_statement, 
the 
delay_expression 
is first evaluated. 
For a 
delay_until_statement, 
the expiration time for the delay is the value of the 
delay_expression, 
in the time base associated with the type of the 
expression. 
For a 
delay_relative_statement, 
the expiration time is defined as the current time, in the time base 
associated with relative delays, plus the value of the 
delay_expression 
converted to the type Duration, and then rounded up to the next clock 
tick. 
The time base associated with relative delays 
is as defined in 
D.9, “
Delay 
Accuracy” or is implementation defined. 
 
The task executing a 
delay_statement 
is blocked until the expiration time is reached, at which point it becomes 
ready again. If the expiration time has already passed, the task is not 
blocked. 
 
The time base associated with the type Time of package 
Calendar is implementation defined. The function Clock of package Calendar 
returns a value representing the current time for this time base. The 
implementation-defined value of the named number System.Tick (see 
13.7) 
is an approximation of the length of the real-time interval during which 
the value of Calendar.Clock remains constant. 
 
 The functions Year, Month, Day, and Seconds return 
the corresponding values for a given value of the type Time, as appropriate 
to an implementation-defined time zone; the procedure Split returns all 
four corresponding values. Conversely, the function Time_Of combines 
a year number, a month number, a day number, and a duration, into a value 
of type Time. The operators "+" and "–" for 
addition and subtraction of times and durations, and the relational operators 
for times, have the conventional meaning. 
If Time_Of is called with a seconds value of 86_400.0, 
the value returned is equal to the value of Time_Of for the next day 
with a seconds value of 0.0. The value returned by the function Seconds 
or through the Seconds parameter of the procedure Split is always less 
than 86_400.0.
 The exception Time_Error is raised by the function 
Time_Of if the actual parameters do not form a proper date. This exception 
is also raised by the operators "+" and "–" 
if the result is not representable in the type Time or Duration, as appropriate. 
This exception is also raised by the functions Year, Month, Day, and 
Seconds and the procedure Split if the year number of the given date 
is outside of the range of the subtype Year_Number. 
Implementation Requirements
The implementation of the type Duration shall allow 
representation of time intervals (both positive and negative) up to at 
least 86400 seconds (one day); Duration'Small shall not be greater than 
twenty milliseconds. The implementation of the type Time shall allow 
representation of all dates with year numbers in the range of Year_Number; 
it may allow representation of other dates as well (both earlier and 
later). 
Implementation Permissions
 An implementation may define additional time types.
Implementation Advice
Whenever possible in an implementation, the value 
of Duration'Small should be no greater than 100 microseconds. 
The time base for 
delay_relative_statements 
should be monotonic; it need not be the same time base as used for Calendar.Clock. 
 
34  A 
delay_statement 
may be executed by the environment task; consequently 
delay_statements 
may be executed as part of the elaboration of a 
library_item 
or the execution of the main subprogram. Such statements delay the environment 
task (see 
10.2).
 
35  
A 
delay_statement 
is an abort completion point and a potentially blocking operation, even 
if the task is not actually blocked.
 
36  There is no necessary relationship between 
System.Tick (the resolution of the clock of package Calendar) and Duration'Small 
(the small of type Duration). 
Examples
Example of a relative 
delay statement: 
delay 3.0;  -- delay 3.0 seconds
Example 
of a periodic task:  
declare
   use Ada.Calendar;
   Next_Time : Time := Clock + Period;
                      -- Period is a global constant of type Duration
begin
   loop               -- repeated every Period seconds
      delay until Next_Time;
      ... -- perform some actions
      Next_Time := Next_Time + Period;
   end loop;
end;
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe