> ## Documentation Index
> Fetch the complete documentation index at: https://docs.truemath.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Authoring dates and durations

> Give a variable a duration, date, datetime, or time-of-day display type, choose the format it renders in, and set a default written the way people write dates.

TrueMath has four display types for dates and durations: `duration`, `date`, `datetime`, and `time`. Setting one on a [variable](/concepts/variables) declares what its number counts and how it is shown.

The value itself stays an ordinary number. Each of these is a count of **seconds** carrying the unit `s`, in the same `"value unit"` form every other quantity uses (see [Units and precision](/concepts/units-and-precision)). What separates a date from a duration is the display type, not the number.

This page covers authoring: the four kinds, their formats, and their defaults. For the arithmetic these values take part in, see [Dates](/math/types/dates) — and read [`mo` and `yr` shift by an average](/math/types/dates#mo-and-yr-shift-by-an-average-not-a-calendar-step) before writing an equation that shifts a date by a term in months. For the spellings a value can be written in, see [Dates, times, and durations](/concepts/input-formats#dates-times-and-durations) under Input formats.

## The four kinds

| Display type | What it is             | The number counts                   | Example value    | Renders as         |
| ------------ | ---------------------- | ----------------------------------- | ---------------- | ------------------ |
| `duration`   | A span of time         | Seconds elapsed                     | `"5405 s"`       | 1:30:05            |
| `date`       | A calendar day         | Seconds since `1970-01-01 00:00:00` | `"1784592000 s"` | 7/21/2026          |
| `datetime`   | A day and a clock time | Seconds since `1970-01-01 00:00:00` | `"1784644205 s"` | 7/21/2026, 2:30 PM |
| `time`       | A time of day          | Seconds since midnight              | `"52205 s"`      | 2:30 PM            |

A `time` counts from midnight rather than from the epoch, which is the same number a `datetime` would hold on 1970-01-01.

In the Builder these appear in the **Display Type** list beside `number`, `percent`, and `no_separator`, each labeled by an example: Duration (1:30:00), Date (7/21/2026), Date & Time (7/21/2026, 2:30 PM), Time of Day (2:30 PM).

Everything else about the variable is unchanged. It takes a key, a title, a description, and a default like any other, and the [guidance for defining any variable](/authoring/defining-variables) applies unaltered. The one difference is that there is no unit to choose: these values are always in seconds, so the unit field is not offered.

## Choosing a format

Every variable has a **decimal format** slot. On an ordinary number it holds a decimal count, `decimals_2`. On one of these four it holds a **format token** instead, and the token has to match the kind: a `date` takes a `date_*` token, and pairing it with `decimals_2` is rejected when you save.

### Duration formats

Rendering `"5405 s"`:

| Token           | Renders   | Reads as                             |
| --------------- | --------- | ------------------------------------ |
| `duration_hms`  | 1:30:05   | 1 hr 30 min 5 sec                    |
| `duration_hm`   | 1:30      | 1 hr 30 min                          |
| `duration_ms`   | 90:05     | 90 min 5 sec                         |
| `duration_ms_3` | 90:05.000 | 90 min 5 sec to three decimal places |

**The leading group is unbounded.** `duration_ms` renders `"5405 s"` as `90:05` rather than `1:30:05` — ninety minutes, not one hour and thirty. A format with no hours group does not drop the hours or roll them over; it counts them as further minutes. So a span of any size renders in whichever format you pick, and nothing is lost off the large end. What can be lost is precision at the small end — see [Two formats do not round-trip](#two-formats-do-not-round-trip).

Rounding is applied to the **total** before it is split into groups, so 59.6 seconds renders as `1:00` and never as `0:60`.

### Date formats

Rendering `"1784592000 s"`:

| Token           | Renders                |
| --------------- | ---------------------- |
| `date_short`    | 7/21/2026              |
| `date_med`      | Jul 21, 2026           |
| `date_long`     | July 21, 2026          |
| `date_full`     | Tuesday, July 21, 2026 |
| `date_my_short` | 7/2026                 |
| `date_my_med`   | Jul 2026               |
| `date_my_long`  | July 2026              |
| `date_iso`      | 2026-07-21             |

### Date and time formats

Rendering `"1784644205 s"`:

| Token            | Renders                  |
| ---------------- | ------------------------ |
| `datetime_short` | 7/21/2026, 2:30 PM       |
| `datetime_med`   | Jul 21, 2026, 2:30 PM    |
| `datetime_long`  | July 21, 2026 at 2:30 PM |
| `datetime_iso`   | 2026-07-21 14:30:05      |

### Time-of-day formats

Rendering `"52205 s"`, seconds past midnight:

| Token        | Renders    |
| ------------ | ---------- |
| `time_short` | 2:30 PM    |
| `time_med`   | 2:30:05 PM |

### US formatting throughout

TrueMath formats dates and times US-style today: numeric dates month-first, English month and weekday names, and a 12-hour clock with AM/PM. That applies on input and on display alike, for every reader, so `10/5/2026` is October 5th everywhere.

The two `_iso` tokens are the exception. `date_iso` renders `2026-07-21` and `datetime_iso` renders `2026-07-21 14:30:05`, which read the same way for everyone. Reach for one where the value is going somewhere ambiguity would cost you.

## Setting a default

A [default](/authoring/defining-variables#default-value-and-unit) on one of these variables is written the way you would write the value by hand. There is no unit to pick and no seconds to work out.

| The variable is | You write           | Stored as        |
| --------------- | ------------------- | ---------------- |
| `date`          | `7/21/2026`         | `"1784592000 s"` |
| `datetime`      | `7/21/2026 2:30 PM` | `"1784644200 s"` |
| `time`          | `2:30 PM`           | `"52200 s"`      |
| `duration`      | `22:47`             | `"1367 s"`       |
| `duration`      | `90 min`            | `"90 min"`       |

Every spelling a user can type is a spelling you can author a default in. The accepted spellings are listed under [Input formats](/concepts/input-formats#dates-times-and-durations); the formats a stored value is *shown* in are [above](#choosing-a-format).

A colon value on a `duration` is read through the variable's format token, so pick the format before you type the default: `22:47` is 1367 seconds under `duration_hms`, `duration_ms`, or `duration_ms_3`, and 82020 seconds under `duration_hm`. See [One genuine ambiguity: the colon](/concepts/input-formats#one-genuine-ambiguity-the-colon).

Two kinds of default are stored as you wrote them rather than converted to seconds:

* **A value that already names a time unit** — `90 min`, `1 hr 30 min` — stays as written and is converted when the calculation runs.
* **A keyword** — `today` and `now` are stored as the word. See [`today` and `now` as defaults](#today-and-now-as-defaults).

A bare number is a count of seconds already, and is stored with the unit: a `duration` default of `90` becomes `"90 s"`.

### What the Builder shows back

Once saved, a default is shown back through the variable's own display type and format token, **not** as the text you typed. Enter `Jul 21, 2026` on a variable formatted `date_short` and it reads back as `7/21/2026`. The two cases above are the exceptions: neither a keyword nor a value carrying its own unit is a count of seconds, so both are shown exactly as written.

<Warning>
  **A default that cannot be read is refused when you save**, by name, with a message listing the spellings that do fit. `2026-02-29` is not a date — 2026 is not a leap year — so it fails at the save rather than becoming something surprising later.
</Warning>

### `today` and `now` as defaults

A default of `today` or `now` is stored as **the word**, not as the date you authored it on. The value used is the current date at the moment the calculation runs, in the caller's own time zone (see [Time zones](/api/calculate#time-zones)). That is how a domain anchors on the current date: a quote valid from today, a closing date thirty days out.

Which keyword fits depends on the kind, and what survives depends on it too:

| The variable is | `today`        | `now`                                                  |
| --------------- | -------------- | ------------------------------------------------------ |
| `date`          | midnight today | midnight today — a date has no clock to carry the rest |
| `datetime`      | midnight today | the current date and time                              |
| `time`          | refused        | the current time of day                                |
| `duration`      | refused        | refused                                                |

The two refusals are refusals rather than readings. Midnight is not what anyone means by "today" on a clock, and neither word names a span. Both are caught when you save, with the same message a misspelled date gets.

A `date` variable keeps only the day from `now` because a time it cannot show would make two identical-looking dates compare unequal.

### Two formats do not round-trip

Both are safe, and both are worth knowing:

* `date_my_short`, `date_my_med`, and `date_my_long` omit the day, so `Jul 2026` read back is the **1st** of July.
* `duration_hm` rounds to the whole minute, so seconds entered are not shown.

Neither loses the stored value. Changing how a default is *displayed* never rewrites it; only editing the field does.

## Dates and durations in tables and charts

A [table](/authoring/tables) variable's own display type is always `table`, so a **column** carries the kind and the format token for the cells beneath it. A payment schedule can put a date column beside a currency column, and each cell is read, stored, and rendered against its own column. A [chart](/authoring/charts) series and a pie slice take the same four kinds a column does.

See [Columns of dates and durations](/authoring/tables#columns-of-dates-and-durations) and [Charting dates and durations](/authoring/charts#charting-dates-and-durations).

## A display type formats, it does not validate

A `date` variable renders **whatever count of seconds it holds** as a date. Nothing checks that the number means a date, because at that point there is nothing left to check: a date is a count of seconds, and so is every number arithmetic produces from one.

TrueMath computes with these as ordinary numbers and blocks exactly one operation, a date plus a bare number (see [A bare number is not a duration](/math/types/dates#a-bare-number-is-not-a-duration)). Everything else goes through. A `closing` of 7/21/2026 is `"1784592000 s"`, so `closing / 2` is half as many seconds — still seconds — and the variable shows it as **April 11, 1998**. A real-looking date, from an equation that means nothing, with no error anywhere.

<Warning>
  **A wrong date looks exactly like a right one.** An equation that produces a nonsense count of seconds produces a nonsense date, and the format token renders it as confidently as any other. This is the same trap as [`mo` and `yr` shifting a date by an average](/math/types/dates#mo-and-yr-shift-by-an-average-not-a-calendar-step), and it is why an unexpected date in a result is worth tracing back to its equation rather than to its display type.
</Warning>

What a `date` variable does **not** show as a date is a value carrying a different unit. A variable that ends up holding `15 ft` is shown as `15 ft`, since feet are not seconds and there is no date to render. A stray unit where a date belongs is a visible signal; a wrong number is not.

## A time of day is not bounded to one day

A `time` variable holds seconds since midnight, but nothing confines it to a single day, and a calculation routinely produces a value outside one. A shift starting at 1:40 PM and running 845 minutes ends at 3:45 AM the next morning, and that is the correct answer.

A time-of-day format shows a clock and nothing else, so 3:45 AM tomorrow and 3:45 AM today render identically. Where the day matters to the reader as well as to the arithmetic, model the value as a `datetime` and let it carry the date.
