Skip to main content
Install Relativities before running the synthetic examples. A Date is a calendar day. Date functions count the days, months or years between two dates and shift a date by a whole count:
The example rates a personal auto policy from the synthetic carrier Example Mutual. Its manual rates on driver age, the policy term, incidents in the last three years, months insured and vehicle age.

Rate a policy from its dates

Save the rater as dates/rater.rsl:
dates/rater.rsl
Send each date as a YYYY-MM-DD string:
The driver is 22 on the effective date, and one incident falls inside the three-year window. The annual premium is 945 × 1.35 × 1.15 × 0.95 × 0.9 = 1254.38.

Declare a date input

State the earliest and latest date the input accepts:
  • Both ends belong to the range.
  • Write _ for an open end, as in [2026-01-01, _].
  • A request sends the date as a string, such as "2026-08-15". For a Python date, send date.isoformat().
The rater refuses a date outside the range, and a string that names a day the calendar lacks:
Refusals lists each reason code.

Compare with a date literal

Write a date in a calculation as YYYY-MM-DD, with the quotes left out:
Dates compare with =, <, <=, > and >=. A policy effective on 1 July 2026 or later takes the revised premium. A literal names a real calendar day. The check reports a literal such as 2026-06-31 with E-DATE.

Calculate an age

diff_years(later, earlier) counts full years, as an age in years is counted:
The driver born on 2003-09-01 is 22 on 2026-08-15 and turns 23 on 2026-09-01.

Calculate the term and the days in force

add_months and add_years shift a date by a whole count. diff_days(later, earlier) counts the days between two dates:
The premium calculation multiplies the annual premium by term_days / 365.
  • Write the count as a whole number in the source, such as 6 or -3.
  • For a count that depends on an input, write one arm for each filed count, as expiration_date does.
  • add_days(date, n) shifts by days in the same way.

Count the months between two dates

diff_months(later, earlier) counts calendar months and ignores the day of the month:
From 2023-02-28, the count is 35 on the last day of January 2026 and 36 one day later:
For a rule that needs 36 full months, compare two dates: self.insured_since <= add_months(self.effective_date, -36).

Count incidents in a look-back window

A negative count shifts a date back. The window starts three years before the effective date:
For the policy effective on 2026-08-15, the window starts on 2023-08-15. The incident on 2024-05-02 counts, and the incident on 2022-11-30 is outside the window. A shifted date stays inside the calendar, which runs from 0001-01-01 to 9999-12-31. The check proves this from the range of the input. A shift back needs an earliest date, and a shift forward needs a latest date. A shift of an input that lacks that end gets E-DATE-RANGE.

Read the year and the month

year(date) gives the year, and month(date) gives the month from 1 to 12:
The manual starts each rating year in October. A policy effective on 2026-10-01 rates a 2021 vehicle as six years old.

Check month ends and leap days

A month or year shift keeps the day of the month. When the target month is shorter, the result is the last day of that month.
  • 31 January plus one month is 28 February, a term of 28 days.
  • 29 February 2028 plus one year is 28 February 2029.
  • 29 February 2028 less three years is 28 February 2025.
diff_years counts a birthday on 29 February from 1 March in a common year:
Compare these results with the day-count rules in the manual before you rely on them.