Date calculations
The Dates and times page covers how Rhyme stores dates. This page covers the datefn set — the actions that do math and comparisons on those dates: adding days, counting the gap between two dates, formatting for display, and more.
Every datefn action returns a value — none of them change a variable in place. Always capture the result with $result = .
Adding and subtracting time
| Action | What it does | Example |
|---|---|---|
add-days | Adds (or subtracts) a number of days | $due = add-days 10 to $start-date |
add-weeks | Adds (or subtracts) a number of weeks | $due = add-weeks 2 to $start-date |
add-months | Adds (or subtracts) a number of months | $due = add-months 3 to $start-date |
add-years | Adds (or subtracts) a number of years | $due = add-years 5 to $start-date |
Each takes a count and a date, connected with to:
$start-date = "2025-01-01"$due = add-days 10 to $start-date// $due is "2025-01-11"
$renewal = add-years 5 to $start-date// $renewal is "2030-01-01"To subtract, use a negative number — but put it in a variable first, since a bare negative literal isn’t accepted here:
$due-date = "2025-01-01"$days-back = -5$reminder-date = add-days $days-back to $due-date// $reminder-date is "2024-12-27"Comparing and counting dates
| Action | What it does | Example |
|---|---|---|
days-between | Number of days from one date to another | $gap = days-between $start-date and $end-date |
days-until | Number of days from today until a date | $countdown = days-until $target-date |
date-after | Whether the first date is strictly after the second | $later = date-after $date-a $date-b |
date-before | Whether the first date is strictly before the second | $earlier = date-before $date-a $date-b |
date-between | Whether today falls within a date range (inclusive) | $in-range = date-between $range-start and $range-end |
$start-date = "2025-01-01"$end-date = "2025-01-31"$gap = days-between $start-date and $end-date// $gap is 30 — order matters: reversing the dates gives a negative number
$target = "2030-06-15"$countdown = days-until $targetdate-after and date-before take two dates with no connecting word, and are strict — equal dates return false:
$date-a = "2025-12-31"$date-b = "2025-01-01"$later = date-after $date-a $date-b// $later is truedate-between is easy to misread — despite the name, it doesn’t compare two arbitrary dates. It always checks whether today falls inside the given range:
$range-start = "2020-01-01"$range-end = "2030-12-31"$in-range = date-between $range-start and $range-end// true if today is anywhere from 2020-01-01 through 2030-12-31, inclusiveBoth today and any of these actions accept the literal word today in place of a date variable, e.g. days-until today or date-after today $deadline.
Reading parts of a date
| Action | What it does | Example |
|---|---|---|
get-day | Day of the month (1–31) | $d = get-day from $date |
get-month | Month number (1–12) | $m = get-month from $date |
get-year | Four-digit year | $y = get-year from $date |
age | Whole years since a birthdate, as of today | $years = age $birthdate |
day-names | The 7 weekday names, Monday first | $weekdays = day-names |
month-names | The 12 month names | $months = month-names |
$sample = "2025-11-14"$day-of-month = get-day from $sample$month-num = get-month from $sample$year-num = get-year from $sample// 14, 11, 2025
$age-years = age "2000-01-01"day-names and month-names take no arguments — they just return the list, localized to the user’s language:
$weekday-names = day-names// ["Monday", "Tuesday", ..., "Sunday"]Formatting and parsing
format-date turns a date into a display string using a template — YYYY for the year, MM for the month, DD for the day:
$sample = "2025-11-14"$display = format-date $sample as "MM/DD/YYYY"// "11/14/2025"parse-date is the reverse: turn a display string into Rhyme’s standard date format, given the template it was written in:
$parsed = parse-date "6/20/13" from "M/D/YY"// "2013-06-20"relative-time gives a human-friendly description of a date relative to today:
$relative = relative-time today// "today"Finding the start and end of a period
| Action | What it does |
|---|---|
start-of-month / end-of-month | First / last day of the date’s month |
start-of-week / end-of-week | Monday / Sunday of the date’s week |
start-of-year / end-of-year | January 1 / December 31 of the date’s year |
$mid-month = "2025-06-15"$month-start = start-of-month $mid-month$month-end = end-of-month $mid-month// "2025-06-01", "2025-06-30"
$week-anchor = "2025-06-18"$week-start = start-of-week $week-anchor$week-end = end-of-week $week-anchor// "2025-06-16" (Monday), "2025-06-22" (Sunday)If the date given is already the start or end of that period, these return the same date unchanged — calling end-of-week on a Sunday just returns that Sunday.
Handling missing results
Like the math actions, a datefn action given a missing or invalid date produces no value instead of an error. Check with if missing:
$event-date = "2026-12-25"$days-left = days-until $event-date
if missing $days-left: .text "No event date set" #red:else .text "Days until the event: {$days-left}" -bold:endComplete example: billing period and reminder
$due = "2026-09-01"$reminder-lead = -7$reminder-date = add-days $reminder-lead to $due
.text "Reminder starts: {$reminder-date}"
$billing-anchor = "2026-03-14"$period-start = start-of-month $billing-anchor$period-end = end-of-month $billing-anchor
.text "Billing period: {$period-start} to {$period-end}"