[comp.lang.ada] Limits on type Duration and package Calendar

mbrinn@bbn.com (Marshall Brinn) (07/03/90)

I have come across a problem with package CALENDAR, and would be interested
in hearing what others have to say/have done about it.


In the LRM, it defines that type DURATION need only ranuge up to 84600.0,
ie., the number of seconds in a day (the definition of CALENDAR.DAY_DURATION).


However, package CALENDAR provides functions "+" and "-" where the difference
between two times is given as a DURATION. How then does this package handle
the difference between two days that are more that one day apart? Some 
compilers I've tried seem to have a reasonably high value for DURATION'last,
at least one (TELESOFT TELEGEN2 1.4) used the one-day upper bound.

Yes, I can "roll my own", but it seems a shame that I can't use the "standard"
calendar interface because it is not sufficient to such a simple task.


Any suggestions on the "Standard" ADA way to deal with time gaps > 1 day
would be appreciated.



Marshall Brinn (mbrinn@bbn.com)
70 Fawcett St.
Cambridge, MA 02138
617-873-2717

rlk@telesoft.com (Bob Kitzberger @sation) (07/06/90)

In article <57925@bbn.BBN.COM>, mbrinn@bbn.com (Marshall Brinn) writes:
>
> In the LRM, it defines that type DURATION need only ranuge up to 84600.0,
> ie., the number of seconds in a day (the definition of CALENDAR.DAY_DURATION).
> 
> However, package CALENDAR provides functions "+" and "-" where the difference
> between two times is given as a DURATION. How then does this package handle
> the difference between two days that are more that one day apart? Some 
> compilers I've tried seem to have a reasonably high value for DURATION'last,
> at least one (TELESOFT TELEGEN2 1.4) used the one-day upper bound.

Since Duration is a fixed-point type, there is a trade-off between high
resolution and a "reasonably high value" -- i.e. high upper bound.  Using a
_minimal_ number of bits to represent the integer portion of Duration (e.g.
17 bits and 1 sign bit) allows a _maximal_ number of bits to represent the
fractional portion, a desirable approach for embedded systems in which accurate
time measurements are important.  For a 32-bit representation of Duration,
this leaves 14 bits to represent the fractional portion, for a resolution 
of about 61 microseconds.

It may be argued that non-embedded systems should have a larger number of 
bits for the integer portion of type Duration, though this begs the question
of how many is enough to represent a "reasonably high value"?  

I know this doesn't answer your question... but maybe it sheds some light on
the trade-offs compiler vendors have to make in implementing Ada's time
abstraction.  Things get much more complicated when you throw in 
System.Tick (which is relatively useless and hard to implement meaningfully), 
network time syhchronization, and low-level hardware timers whose values
don't map exactly onto a binary fraction.

IMHO, Calendar is trying to handle the time abstraction for two different
problem domains that are better left separate -- 1) time-of-day calculations,
and 2) real time measurements.  Type Duration is the "bridge" between the
two abstractions.  Sigh.

It looks to me like you'll need to "roll your own" solution, with calls to
Calendar.Split to get the yr/mon/day/sec fields of both timne operands.

	Bob Kitzberger
	Software Engineer, Ada Tasking

-- 
Bob Kitzberger               Internet : rlk@telesoft.com
TeleSoft                     uucp     : ...!ucsd.ucsd.edu!telesoft!rlk
5959 Cornerstone Court West
San Diego, CA   92121-9891   "There's too much caffeine in your bloodstream..."
(619) 457-2700 x163                                              -- The Smiths
------------------------------------------------------------------------------

eachus@linus.mitre.org (Robert I. Eachus) (07/06/90)

     There is a UI (UI-16) on the proper definition of type DURATION.
It specifies that DURATION'SIZE should be at least 32 and that
DURATION'SMALL should be at most 2.0**-14 (61.035 microseconds).  It
also specifies that 1.0 must be a model number.

     For those that are unfamiliar with UI's, they are recommendations
on implementation specific features of Ada, and are in addition to the
RM. While AI's are interpretations of what the RM says.  At the June
meeting of WG9 several UI's, including this one, were formally adopted.
This UI is a perfect example of what a UI should be.  It allows a user
to depend on more than it is possible to say in the reference manual,
while still leaving necessary freedom for implementations on machines
with other than 16 or 32 bit word sizes.
--

					Robert I. Eachus

with STANDARD_DISCLAIMER;
use  STANDARD_DISCLAIMER;
function MESSAGE (TEXT: in CLEVER_IDEAS) return BETTER_IDEAS is...

madmats@elcgl.epfl.ch ("", Mats Weber) (07/09/90)

RFC-822-Headers:
Received: from elcgl.epfl.ch by SIC.Epfl.CH with VMSmail ; Sun, 8 Jul 90 19:46:19 N
X-ST-Vmsmail-To: gw::"info-ada@ajpo.sei.cmu.edu"

==================

Marshall Brinn (mbrinn@bbn.com) writes:

>[stuff deleted...]
>Any suggestions on the "Standard" ADA way to deal with time gaps > 1 day
>would be appreciated.

There are good reasons for not requiring the type Duration to cover more 
that one day (fixed point type implementable using one machine-word on most 
CPUs).

However, I think that Calendar should have defined another Duration type 
that enables handling longer time intervals, as is done in the package spec 
below.

The complete portable implementation source code may be obtained on request 
by sending e-mail to:

Mats Weber
Swiss Federal Institute of Technology
EPFL DI LGL
1015 Lausanne
Switzerland

E-mail : madmats@elcgl.epfl.ch
phone  : +41 21 693 52 92
fax    : +41 21 693 39 09


-------------------------------------------------------------------------
-- ADDITIONAL CALENDAR FUNCTIONS
   -----------------------------

-- Creation : 19-JAN-1987 by Mats Weber.


with Calendar;

use Calendar;

package Extended_Calendar is
-------------------------

   type Long_Duration is private;

   type Day_Interval is 
      range -366 * Year_Number'Last..366 * Year_Number'Last;

   subtype Natural_Day_Interval is Day_Interval range 0..Day_Interval'Last;

   type Duration_Sign is ('+', '-');


   function To_Long_Duration (Days    : Natural_Day_Interval;
                              Seconds : Day_Duration;
                              Sign    : Duration_Sign := '+') 
      return Long_Duration;

   function To_Long_Duration (Seconds : Day_Duration;
                              Sign    : Duration_Sign := '+') 
      return Long_Duration;

   function To_Long_Duration (Days    : Natural_Day_Interval;
                              Sign    : Duration_Sign := '+') 
      return Long_Duration;

   function Days    (Delta_Time : Long_Duration) 
      return Natural_Day_Interval;
   function Seconds (Delta_Time : Long_Duration) return Day_Duration;
   function Sign    (Delta_Time : Long_Duration) return Duration_Sign;

   function To_Duration (Delta_Time : Long_Duration) return Duration;

   function Zero return Long_Duration;


   function "+" (A : Long_Duration) return Long_Duration;
   function "-" (A : Long_Duration) return Long_Duration;

   function "abs" (A : Long_Duration) return Long_Duration;

   function "+" (A, B : Long_Duration) return Long_Duration;
   function "-" (A, B : Long_Duration) return Long_Duration;

   function "*" (N : Integer; A : Long_Duration) return Long_Duration;
   function "*" (A : Long_Duration; N : Integer) return Long_Duration;
   function "/" (A : Long_Duration; N : Integer) return Long_Duration;

   function "<"  (A, B : Long_Duration) return Boolean;
   function "<=" (A, B : Long_Duration) return Boolean;
   function ">"  (A, B : Long_Duration) return Boolean;
   function ">=" (A, B : Long_Duration) return Boolean;

   function "+" (T : Time; A : Long_Duration) return Time;
   function "+" (A : Long_Duration; T : Time) return Time;
   function "-" (T : Time; A : Long_Duration) return Time;
   function "-" (T1, T2 : Time) return Long_Duration;
      -- Will raise TIME_ERROR if no valid time value can be returned.


   type Week_Day is (Monday, Tuesday, Wednesday, Thursday, 
                     Friday, Saturday, Sunday);

   function Succ (Day : Week_Day) return Week_Day;
   function Pred (Day : Week_Day) return Week_Day;

   function Day_Of_Week (Date : Time := Clock) return Week_Day;

   function Day_Of_Week (Year  : Year_Number;
                         Month : Month_Number;
                         Day   : Day_Number) return Week_Day;

private

   type Long_Duration is
      record
         Days    : Natural_Day_Interval;
         Seconds : Day_Duration;
         Sign    : Duration_Sign;
      end record;

end Extended_Calendar;