The interval type in Rax represents a duration
starting at a given point in time and ending at a given point in time. For example,
"yesterday" or "today, from 9am to 5pm."
The timeinterval type is denoted by the 
symbol in Rax.
The ISO 8601 strings for intervals are somewhat more complex but still logical extensions
of the ones mentioned above. Also time, absolute and relative values can be grouped (using
[
and ]
) and cast to interval using
()
like so:
: over_5_weeks := ()"20130712T03:44/20130822T12:32"; : twenty_four_ := ()[(@)"now",(^)"P1D"];
A tuple needs to be of one of the following types to be cast to an
interval: [@:begin, @:end]
, [@:begin,
^:duration]
, [@:begin,
~:duration]
, [^:duration,
@:end]
, [~:duration, @:end]
.
The cast to an interval from a tuple, is straightforward but can look intimidating,
especially when the tuple is populated with casted strings itself. Therefore Rax has an
create interval operator 
..., ... 
that takes
two arguments that can be either a literal string, time, absolute or relative. Note
that string arguments do not need to be cast to a temporal type. If it starts with a
"P"
it is taken to be a relative duration. This makes the two
definitions below equivalent.
: twenty_four2 := ()[(@)"now",(^)"P1D"]; : twenty_four3 := "now","P1D";
Obviously intervals cannot be added or multiplied. However, using the
<:
(element of) and :>
(contains) operators, it is possible to check if a given point in
time falls within an interval. For example:
: some_week := ()"20111018T00:00:00/P1W"; `print (@)"20111021" <: some_week; // Output: true `print some_week :> (@)"20141021"; // Output: false
Note that the begin point of an interval falls within this interval, while the end point doesn't, which is illustrated by the following code snippet:
@:begin := (@)"now"; @:end := begin + (^)"PT1H"; :interval := ()[begin, end]; `print begin <: interval; // Output: true `print end <: interval; // Output: false
The following table summarizes the operators defined
on 
.
Table 4.4. Operators defined on 
Syntax  Explanation 

i1 := i2  Assignment 
i1 == i2  Equals 
i1 != i2  Not equals 
t <: i  Element of, i is of
type  . Returns true ,
if the point in time t is an element of
the interval i . For example:
(@)"20140913" <: ()"20140911/P1W" is
true.

i :> t  Contains, i is of
type  . Returns true ,
if the interval i contains the point in
time t . For
example: ()"20140911/P1W" :>
(@)"20140913" .

i << d 
Left shift, i is of type  ,
d is of type ^ or
~ . Returns the interval value where a duration of
d has been subtracted from both the begin and the
end of the interval. The interval i has been shifted back
in time by a duration of d .
For example: ()"20140911/P1W" << (^)"P1D" .

i >> d 
Right shift, i is of type  ,
d is of type ^ or
~ . Returns the interval value where a duration of
d has been added to both the begin and the end of the
interval. The interval i has been shifted forward in time
by a duration of d .
For example: ()"20140911/P1W" >> (^)"P1D" .

There are also many useful operators defined on sets of tuples containing
intervals, such as @&@
(temporal and) which we've
already met in Chapter 2, Getting started. For example, to compute an overlap of
two intervals:
: a_week := ()"20111018T00:00:00/P1W"; : another_week := ()"20111017T00:00:00/P1W"; {}: overlap := {[a_week]} @&@ {[another_week]}; `print overlap; // Output: {20111018T00:00:00/20111024T00:00:00}
Such temporal operators enable intuitive and succinct code for temporal data manipulation. In Chapter 8, Ordered sets, the section called “Temporal relational operators”, we will meet more of these operators.