[[Property:title|Duration]]
[[Property:weight|1]]
[[Property:uuid|64672bd0-b696-0c39-1e30-5ac64aae4a99]]
The classes <eiffel>TIME_DURATION</eiffel>, <eiffel>DATE_DURATION</eiffel>, and <eiffel>DATE_TIME_DURATION</eiffel> model time durations.

The classes dealing with duration inherit from <eiffel>DURATION</eiffel>, which in turn inherits from <eiffel>GROUP_ELEMENT</eiffel> and <eiffel>PART_COMPARABLE</eiffel>. From this lineage comes the query <eiffel>zero</eiffel>, the addition features <eiffel>infix +</eiffel> and <eiffel>infix -</eiffel> and the unary features <eiffel>prefix +</eiffel>, and <eiffel>prefix -</eiffel>. 

Duration is used as an amount of time, without link to an origin. It may be added to the respective absolute notion So, <eiffel>TIME + TIME_DURATION</eiffel> is possible, but not <eiffel>TIME + DATE_TIME_DURATION</eiffel> nor <eiffel>DATE_TIME + TIME_DURATION</eiffel> ... see classes <eiffel>TIME</eiffel>, <eiffel>DATE</eiffel>, and <eiffel>DATE_TIME</eiffel> in [[Absolute time]]. 

Attributes of durations are allowed to take values which do not fall in the expected range, even negative values (e.g., <eiffel>hour = -1</eiffel>, <eiffel>minute = 75</eiffel>, <eiffel>day = 40</eiffel>...). However, queries are available in each class to test for canonical format and to provide equivalent instances in canonical format. 

An instance is ''canonical'' if the values for all of its relevant attributes fall into the specific ranges defined for each type of duration, documented in sections below (for example, for a canonical instance of <eiffel>TIME_DURATION</eiffel>, the value of <eiffel>second</eiffel> will be in 0..59). In such a case, the value of query <eiffel>canonical</eiffel> is <eiffel>True</eiffel>. For example, an instance of <eiffel>TIME_DURATION</eiffel> such as 12:-10:60 is not canonical. The query <eiffel>to_canonical</eiffel> will return a new instance with equivalent value, but with its components in canonical form, in the case of our example: 11:51:0. These features are also present in <eiffel>DATE_DURATION</eiffel> and <eiffel>DATE_TIME_DURATION</eiffel>. 

Ordering is partial for <eiffel>DATE_DURATION</eiffel> and <eiffel>DATE_TIME_DURATION</eiffel> for reasons explained below, and total for <eiffel>TIME_DURATION</eiffel>. 

==TIME_DURATION==

====Creation====

Instances can be created either by specifying a value for each of the attributes <eiffel>hour</eiffel>, <eiffel>minute</eiffel>, and <eiffel>second</eiffel> (<eiffel>make</eiffel>), or by specifying only a number of seconds (<eiffel>make_by_seconds</eiffel>). Any integer value is accepted. So, for example, it is possible to create a duration with 1 hour and -60 minutes.

====Access====

The query <eiffel>zero</eiffel> provides a <eiffel>TIME_DURATION</eiffel> with 0 hour, 0 minute and 0 second. 

The total number of seconds in the current duration can be obtained by applying the query <eiffel>seconds_count</eiffel>.

====Comparison====

Instances of <eiffel>TIME_DURATION</eiffel> may be compared. The order is the order of the respective total number of seconds. So, 1:-40:0 is less than 0:0:1800, for example. Functions <eiffel><</eiffel>, <eiffel>></eiffel>, <eiffel><=</eiffel>, and <eiffel>>=</eiffel> are available. The <eiffel>BOOLEAN</eiffel> query <eiffel>is_equal</eiffel> (or the object equality operator <eiffel>~</eiffel>) tests object equality, <eiffel>=</eiffel> will compare references. 

====Element change====

Set <eiffel>hour</eiffel>, <eiffel>minute</eiffel>, and <eiffel>second</eiffel> with <eiffel>set_hour</eiffel>, <eiffel>set_minute</eiffel>, and <eiffel>set_second</eiffel>. Arguments do not need to satisfy any range rule.

====Operations====
* Add hours, minutes and seconds with features <eiffel>hour_add</eiffel>, <eiffel>minute_add</eiffel> and <eiffel>second_add</eiffel>.
* <eiffel>infix</eiffel> <eiffel>+</eiffel> and <eiffel>infix</eiffel> <eiffel>-</eiffel> are available for producing sums and differences of durations.
* <eiffel>prefix</eiffel> <eiffel>-</eiffel> is available for producing the inverse of a duration.

====Conversion====

Two features provide a conceptual link with the notion of ''day'':
* The first, <eiffel>to_days</eiffel> returns the number of days equivalent to the current duration. For example, a duration such as 23:60:0 is equivalent to one day. For negative duration, the result is never 0. -1 hour is equivalent to -1 day (i.e. the result of <eiffel>to_days</eiffel> is -1). 
* The second is <eiffel>time_modulo_day</eiffel>. This query returns an instance of <eiffel>TIME_DURATION</eiffel>. The result represents the difference between the current duration and the number of days yielded by <eiffel>to_days</eiffel>. It implies that the result is always positive and less than one day. 

{{sample|Suppose the value of an instance of <eiffel>TIME_DURATION</eiffel> is 25:70:600. Then applying <eiffel>to_days</eiffel> will return 1 (one day) and applying <eiffel>time_modulo_day</eiffel> will return 2:20:0. Now suppose that the value of the <eiffel>TIME_DURATION</eiffel> is negative, say -23:-80:300. In this case, applying <eiffel>to_days</eiffel> will return -2 (minus two days) and <eiffel>time_modulo_day</eiffel> will return 23:45:0.}}


Durations may be in canonical or non-canonical form. This can be tested using the <eiffel>BOOLEAN</eiffel> query <eiffel>canonical</eiffel>. Canonical form depends upon whether the features <eiffel>hour</eiffel>, <eiffel>minute</eiffel>, and <eiffel>second</eiffel> have values that fall into a particular range. An instance of <eiffel>TIME_DURATION</eiffel> is canonical if: 
:* in the case of a positive duration (> zero), all of the three features have to be positive or 0, <eiffel>minute</eiffel> and <eiffel>second</eiffel> less than 60.
:* in the case of a negative duration (< zero), all of the three features have to be negative or 0, <eiffel>minute</eiffel> and <eiffel>second</eiffel> strictly greater than -60. 

Two queries help you work with canonical form:
* The value of the query <eiffel>canonical</eiffel> is <eiffel>True</eiffel> if duration is in canonical form. 
* The query <eiffel>to_canonical</eiffel> yields a new, canonical <eiffel>TIME_DURATION</eiffel> equivalent to the duration to which it is applied.


==DATE_DURATION==

<eiffel>DATE_DURATION</eiffel> is similar to <eiffel>TIME_DURATION</eiffel>, but models durations in dates rather than times. Dealing with the Gregorian calendar is complicated by its irregularities. For example, a date duration of one month may be equal to 28, 29, 30, 31 days, depending on a date of reference. Sometimes though, it is useful to deal with a precise date duration, just a number of days, independent of any particular date. This issue leads to a unique point of design in the <eiffel>DATE_DURATION</eiffel> class: a separation is made between two kinds of instances: ''definite'' date durations and the ''relative'' date durations. The <eiffel>BOOLEAN</eiffel> query <eiffel>definite</eiffel> is <eiffel>True</eiffel> for definite date durations and false for relative date durations. 

An instance is ''definite'' if and only if its attributes <eiffel>month</eiffel> and <eiffel>year</eiffel> are 0. Then only the number of days is used. 

''Relative'' (non-definite) durations allow their attributes <eiffel>year</eiffel>, <eiffel>month</eiffel>, and <eiffel>day</eiffel> to have meaningful values, but disallow comparisons with other durations, for reasons which will be explained below. 

The distinction between definite and relative date duration makes a difference when a duration is added to a date. In the case of a definite <eiffel>DATE_DURATION</eiffel>, there is no ambiguity: a given number of days is added to the date. In the case of a relative <eiffel>DATE_DURATION</eiffel>, the result is relative to the duration's <eiffel>origin_date</eiffel>. For example, a one month duration may be equal to 28 days if the date is in February or 31 days if the date is in August.  

===About ''relative'' DATE_DURATIONs===

Relative durations cannot be compared with any other durations (including zero). This is because of the complexities of the Gregorian calendar. If we consider how many days there are in a duration of one month, we cannot point to a specific integer value that will be correct in all cases ... it depends upon which month we are considering ... and in some cases whether it is a leap year.

If a comparison (<eiffel>></eiffel> or <eiffel><</eiffel>) is applied in a state in which either the current instance or the argument or both are relative durations, the result will be always <eiffel>False</eiffel>. 

We are able to determine if two durations have equal value by applying the feature <eiffel>is_equal</eiffel> (or the object equality operator <eiffel>~</eiffel>). 

When adding a relative <eiffel>DATE_DURATION</eiffel> to a <eiffel>DATE</eiffel>, the years and the months are added first, then the date may be cut (for example, June 31 cut to June 30) and finally the days are added. For example, if one month is added to the date August 31st, the result is September 30th.

Nevertheless, there is a way to compare relative durations: a relative date_duration may be canonical. It means that the duration has its attributes <eiffel>month</eiffel> and <eiffel>day</eiffel> in a fixed range. <eiffel>month</eiffel> must be between 1 and 12, and <eiffel>day</eiffel> larger than 1 and less than a value between 27 and 30. This value is fixed simply: (in the case of a positive duration) when setting day to 0 and adding one more month, the addition of the start date and this new duration must yield a date strictly after the final date (yielded by adding date and tested duration). For example is 0/0/30 (i.e. 0 year, 0 month and 30 days) canonical?
* If the origin date is 01/15 (15th of January), the final date is 02/14. We cannot convert 30 days into 1 month in this case. The duration is canonical.
* If the origin date is 04/15 (15th of April), the final date is 05/15. The duration is not canonical since it is possible to convert days into 1 month. The origin date is used to determine whether the duration is positive or not. If the final date is after the origin date the duration is positive, otherwise it is negative. That does not mean we can compare it to zero, that is only used to determine the sign of the canonical standard. If the duration is negative, it is canonical only if all the attributes are negative.

A way to compare two relative durations is to make them canonical from the same date, and then to compare the fields. It is the same as adding the durations to the same date, and to compare the final dates to each other.

===About ''definite'' DATE_DURATIONs===

Definite durations are characterized by the attribute <eiffel>day</eiffel>. Whenever a duration has its attributes <eiffel>year</eiffel> and <eiffel>month</eiffel> equal to 0, this duration is then definite. On the other hand, if one of these two attributes is not 0, the duration is relative.

The number of days between an origin date and the result of (date + duration) does not depend on the origin date. It is possible to compare definite date_duration to each other.The order is the one of day.

A definite duration may be canonical or not. It is canonical if the number of day is small enough.

===General description===

====Creation====

Two creation features are available: <eiffel>make</eiffel> takes three arguments (<eiffel>year</eiffel>, <eiffel>month</eiffel>, and <eiffel>day</eiffel>). If year and month are null, the duration will be definite; <eiffel>make_by_days</eiffel> takes only the number of day. The duration is automatically definite.

====Comparison====

Features <eiffel><</eiffel>, <eiffel>></eiffel>, <eiffel><=</eiffel>, and <eiffel>>=</eiffel> are available. If both instances are definite, numbers of days are compared. If one of them is non-definite, the result is False.

====Element change====

Features <eiffel>set_day</eiffel>, <eiffel>set_month</eiffel>, and <eiffel>set_year</eiffel> are available to set one of these three attributes <eiffel>day</eiffel>, <eiffel>month</eiffel>, <eiffel>year</eiffel>.

====Operations====
* Add years, months and days with features <eiffel>year_add</eiffel>, <eiffel>month_add</eiffel>, and <eiffel>day_add</eiffel>.
*  <eiffel>DATE_DURATION</eiffel> inherits from <eiffel>GROUP_ELEMENT</eiffel>. <eiffel>infix</eiffel> and <eiffel>prefix</eiffel> <eiffel>+</eiffel>, <eiffel>infix</eiffel> and <eiffel>prefix</eiffel> <eiffel>-</eiffel> are available to compose instances of each other. 

====Conversion====
* <eiffel>to_canonical</eiffel> is used to get a new duration equivalent to the current one and canonical. It needs an argument from class <eiffel>DATE</eiffel>, which is the origin of calculations. 
* <eiffel>to_definite</eiffel> is used to get a new duration equivalent to the current one and definite. As with the previous feature, one argument is needed.
* <eiffel>to_date_time</eiffel> is used to get an instance of <eiffel>DATE_TIME_DURATION</eiffel>. It will have the same date of the current duration and time set to zero. 

==DATE_TIME_DURATION==

<eiffel>DATE_TIME_DURATION</eiffel> is client of <eiffel>DATE_DURATION</eiffel> and <eiffel>TIME_DURATION</eiffel>. Most of the common features described in <eiffel>DATE_DURATION</eiffel> are present in the class. The class deals with its attributes date and time in the same way as <eiffel>DATE_TIME</eiffel>. 

There are, as in <eiffel>DATE_DURATION</eiffel>, definite and non-definite durations. It is the date part which gives the definite non-definite status. Features <eiffel>canonical</eiffel> and <eiffel>to_canonical</eiffel> are present in <eiffel>DATE_TIME_DURATION</eiffel>. They have to deal with the attributes time. 

====Creation====

There are still several ways to create an instance:
* Provide values for all the components of date and time (<eiffel>make</eiffel>). 
* Provide a value for day and values for all the components of time. The instance is then definite (<eiffel>make_definite</eiffel>).
* by gathering an instance of <eiffel>DATE</eiffel> with an instance of <eiffel>TIME</eiffel> (<eiffel>make_by_date_time</eiffel>). This feature copies the references of its arguments, so that if the time (or the date) is changed, the instance previously initialized will be also changed. If this effect has to be avoided, the use of twins is required. 
* by encapsulating an instance of <eiffel>DATE</eiffel> (<eiffel>make_by_date</eiffel>). The attribute <eiffel>time</eiffel> is set to zero, i.e. 0:0:0. The attribute <eiffel>date</eiffel> is set with the same reference than the argument. 

====Access====

<eiffel>seconds_count</eiffel> is the amount of seconds of the time part only. To get the total amount of seconds of the current duration, first shift it to a definite duration, then multiply day by the number of seconds in day and add to it <eiffel>seconds_count</eiffel>. Take care that the duration is not more than 68 years. If it is, the number of seconds will be larger than 2 billion, which is the upper limit for INTEGER (4 bytes).

====Comparison====

The rules are the same than those for <eiffel>DATE_DURATION</eiffel>. Features <eiffel><</eiffel>, <eiffel>></eiffel>, <eiffel><=</eiffel>, and <eiffel>>=</eiffel> are available. If both instances are definite, numbers of days are compared. If one of them is non-definite, the result is False. 

====Element change====

It is possible to change reference of time and date with the features <eiffel>set_time</eiffel> and <eiffel>set_date</eiffel>. To change only one element (for example <eiffel>hour</eiffel>), features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel> have to be used. 

====Operations====
*  <eiffel>DATE_TIME_DURATION</eiffel> inherits from <eiffel>GROUP_ELEMENT</eiffel>. <eiffel>infix</eiffel> and <eiffel>prefix</eiffel> <eiffel>+</eiffel>, <eiffel>infix</eiffel> and <eiffel>prefix</eiffel> <eiffel>-</eiffel> are available to compose instances to each other. 
* Only <eiffel>day_add</eiffel> is present. To add only one element, features from <eiffel>TIME_DURATION</eiffel> or <eiffel>DATE_DURATION</eiffel> have to be used. 

====Conversion====
* <eiffel>canonical</eiffel> and <eiffel>to_canonical</eiffel> are available in the class. To be canonical an instance of the class must have its attributes <eiffel>time</eiffel> and <eiffel>date</eiffel> canonical. Then time must have the same sign than the one of the current duration. The sign of the current instance is determined by adding it to the argument (from <eiffel>DATE_TIME</eiffel>). That will yield a final date. If this final date is after the origin (= the argument), the current duration is considered positive. Otherwise, it is considered negative. Finally time must be less than one day (if positive) or more than minus one day (if negative). <eiffel>to_canonical</eiffel> returns a duration equivalent to the current one (for the argument) and canonical. 
* <eiffel>time_to_canonical</eiffel> looks like <eiffel>to_canonical</eiffel> but focuses mainly on time. It requires a definite duration so that it is possible to compare it to zero. It yields a definite duration equivalent to the current one with a canonical time. <eiffel>hour</eiffel> is then cut so that it stands in the range of one day (0 to 23 if positive and -23 to 0 if negative). The attribute <eiffel>day</eiffel> is also modified to keep the result equivalent to the current duration. <eiffel>time_to_canonical</eiffel> does not need any argument because only time and day are modified.




