The relative type in Rax
represents a duration of a relative amount of time. For example, "one
month" or "ten years." A month and a year are relative durations,
because one cannot say how long they take without anchoring them in a
specific point in time. For example, one month from the 20th of February
2013 will take 28 days, while one month from the 20th of March 2013 will
take 31 days. The same holds for year: 1 year from the 1st of January
2012 will take 366 days, while 1 year from the 1st of January 2013 will
take only 365 days.
Having a relative duration type in Rax often prevents checks for leap
years and allows intuitive handling of adding years or months without
having to analyze where the leap days are or even how many days are
in what month.
The relative type is denoted by the ~
symbol in Rax.
As with time and absolute, relative duration can be derived from
strings and added to other typed values. For example, these are all
valid:
~: months'11 := (~)"P1Y"  (~)"P1M"; `print 2 * months'11; @: now_in_one_year := (@)"now" + (~)"P1Y";
For convenience, relative durations can also have an absolute portion. So the following code is legal in Rax:
~: one'month_one'day := (~)"P1M1D"; ~: one'year_eight'months_two'weeks_six'days := one'month_one'day * 20;
The relative and absolute parts in relative durations behave a bit like real and imaginary parts in complex numbers. For example, you can add two relatives by adding their relative and absolute parts:
`print (~)"P2M3D" + (~)"P4M1DT3H"; // Output: P6M4DT3H
Also, like with complex numbers, the >
operator
and friends are not defined on relatives.
The table below lists the operators defined on ~
.
Table 4.3. Operators defined on ~
Syntax  Explanation 

rd1 := rd2  Assignment 
rd1 == rd2  Equals 
rd1 != rd2  Not equals 
rd1 + rd2  Addition. Relative and absolute parts are added
separately, for example: (~)"P2M3D" + (~)"P4M1DT3H"
== (~)"P6M4DT3H" .

rd1  rd2  Subtraction. Relative and absolute parts are
subtracted separately, for example: (~)"P4M1DT3H" 
(~)"P2M3D" == (~)"P2M1DT21H" .

rd * n  Multiplication, where n is of
type # . Relative and absolute parts are
multiplied separately, for example: (~)"P6M1D" *
2 == (~)"P1Y2D" .

n * rd  Multiplication, where n is of
type # . Relative and absolute parts are
multiplied separately, for example: 2 * (~)"P6M1D"
== (~)"P1Y2D" .

rd / n  Division, where n is of
type # . Relative and absolute parts are
divided separately, for example: (~)"P4M6D" /
2 == (~)"P2M3D" . Note that the relative part is
always rounded down to whole months.

rd * r  Multiplication, where r is of
type & . Relative and absolute parts
are multiplied separately, for example: (~)"P1M2D" *
2.5 == (~)"P2M5D" . Note that the relative part is
always rounded down to whole months.

r * rd  Multiplication, where r is of
type & . Relative and absolute parts
are multiplied separately, for example: 2.5 * (~)"P1M2D"
== (~)"P2M5D" . Note that the relative part is
always rounded down to whole months.

rd / r  Division, where r is of
type & . For example: (~)"P3M4D" /
1.5 == (~)"P2M2DT16H" . Note that the relative
part is always rounded down to whole months.

t + rd  Addition, rd is of
type ~ . Returns a point in time resulting
from shifting t forward by the relative
duration rd . For example:
(@)"20140911" + (~)"1Y1M" == (@)"20151011" .

t  rd  Subtraction, rd is of
type ~ . Returns a point in time resulting
from shifting t backwards by the relative
duration rd . For example:
(@)"20140911"  (~)"1Y1M" == (@)"20130811" .
