# Arithmetic and comparison

Add a duration to an instant to get a later instant, and take one instant
from another to get the time between them:

- `Instant + Duration`, `Duration + Instant` and `Instant - Duration` give an
  `Instant` of the instant's own named type, so you don't build it again.
- `Instant - Instant` gives the `Duration` between them, which is negative
  when the second is later.
- `Duration + Duration` and `Duration - Duration` give a `Duration`.

As with numbers, both sides must be the same type after widening, or one
must be a literal. Two durations of the same named type give a plain
`Duration`.

Instants, dates and durations order with `<`, `<=`, `>` and `>=`, and
compare with `==` on the timeline, so `12:00Z` equals `13:00+01:00`.

A `CalendarDate` has no clock time, so a `Duration` doesn't move it. It
moves by calendar days with `temporal.add_days`. A `ZonedTime` moves on its
calendar the same way, or through its instant. `*`, `/` and `%` don't take
time values.

```jadpo
type DueAt = Instant {}

type ReminderNotice = Duration {
    min: 1m
    max: 7d
}

type Lateness = Duration {}

/// When to send a reminder: the notice before the due time. Taking a
/// duration from a `DueAt` gives a `DueAt`.
function reminder_time(due_at: DueAt, notice: ReminderNotice) -> DueAt {
    return due_at - notice
}

/// How late something done at `done_at` was: negative when it was early.
function lateness(due_at: DueAt, done_at: DueAt) -> Lateness {
    return Lateness(done_at - due_at)
}

test "a duration moves an instant and keeps its type" {
    assert reminder_time("2026-10-25T09:00:00Z", 30m) == "2026-10-25T08:30:00Z"
    assert lateness("2026-10-25T09:00:00Z", "2026-10-25T11:15:00Z") == 135m
    assert lateness("2026-10-25T09:00:00Z", "2026-10-25T08:00:00Z") < 0s
}

test "instants compare on the timeline" {
    assert DueAt("2026-10-25T12:00:00Z") == DueAt("2026-10-25T13:00:00+01:00")
    assert DueAt("2026-10-25T12:00:00Z") < DueAt("2026-10-25T12:00:00.001Z")
}
```
