~ (Relative)

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 ~

SyntaxExplanation
rd1 := rd2Assignment
rd1 == rd2Equals
rd1 != rd2Not equals
rd1 + rd2Addition. Relative and absolute parts are added separately, for example: (~)"P2M3D" + (~)"P4M1DT3H" == (~)"P6M4DT3H".
rd1 - rd2Subtraction. Relative and absolute parts are subtracted separately, for example: (~)"P4M1DT3H" - (~)"P2M3D" == (~)"P2M-1DT-21H".
rd * nMultiplication, where n is of type #. Relative and absolute parts are multiplied separately, for example: (~)"P6M1D" * 2 == (~)"P1Y2D".
n * rdMultiplication, where n is of type #. Relative and absolute parts are multiplied separately, for example: 2 * (~)"P6M1D" == (~)"P1Y2D".
rd / nDivision, 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 * rMultiplication, 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 * rdMultiplication, 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 / rDivision, where r is of type &. For example: (~)"P3M4D" / 1.5 == (~)"P2M2DT16H". Note that the relative part is always rounded down to whole months.
t + rdAddition, rd is of type ~. Returns a point in time resulting from shifting t forward by the relative duration rd. For example: (@)"2014-09-11" + (~)"1Y1M" == (@)"2015-10-11".
t - rdSubtraction, rd is of type ~. Returns a point in time resulting from shifting t backwards by the relative duration rd. For example: (@)"2014-09-11" - (~)"1Y1M" == (@)"2013-08-11".