<!-- Value Types -->

# Special forms keep meaning visible before tools interpret it.

This page explains AEON value choices as language features. It is not the exhaustive lookup table. Use it when you want to understand why AEON separates ordinary numbers from NaN, absence from custom null reasons, and WTC temporal context from a bare UTC offset.

The reference page lists every type mechanically. This page focuses on the forms that change how authors and tools reason about a document.

```aeon
title:string = "Daily note"
body:prose = >`
  Multiline text that can carry prose.
`

count:number = 42
reading:nan = NaN
limit:infinity = Infinity

ready:boolean = true
state:toggle = on
missing:null = !notSet

color:hex = #ff00aa
bits:radix[2] = %1011
payload:base64 = &QmFzZTY0IQ==
code:encoding["base58"] = &FFF

target:sansa = $.contact.name
selector:sansa = $.inventory.items.*.sku

day:date = 2026-05-05
clock:time = 09:30Z
stamp:datetime = 2026-05-05T09:30:00Z
zoned:wtc = 2026-05-05T09:30Z&Australia/Melbourne
local:wtc = 2026-05-05T09:30&local
tai:wtc = 2026-01-01T09:10:10&TAI
```

[Special values](#special-values)  
[Date and time](#date-time)  
[SANSA](#sansa-addresses)  
[Semantic comments](#semantic-comments)  
[Open reference](/type-reference.php)

<!-- Special Values -->

## Absence and numeric edge cases stay explicit.

AEON keeps ordinary numbers separate from IEEE-style edge cases. NaN belongs to the nan literal family, and Infinity belongs to the infinity family. They are not silently accepted as ordinary number values.

Null is also typed. Instead of collapsing every kind of absence into one undifferentiated value, AEON lets a document say whether something is not set, not applicable, tombstoned, or absent for a custom reason.

The advantage shows up at schema time. A consumer can decide whether a field is allowed to contain NaN, Infinity, or a null reason at all. If the schema rejects those forms, downstream materialized values can be used without silently carrying an edge case into math, storage, or business logic.

```aeon
count:number = 42
reading:nan = NaN
negativeReading:nan = -NaN
limit:infinity = Infinity
floor:infinity = -Infinity

email:null = !notSet
fax:null = !notApplicable
oldRecord:null = !tombstone
review:null = !"awaiting manual review"
```

<!-- Date and Time -->

## WTC preserves temporal context.

Plain date values are calendar dates. Plain time values are times of day. A datetime can include UTC or an offset, which is enough when the only thing you need is the instant.

WTC (With Temporal Context) is important when the context used to interpret or present a temporal value is part of the meaning. An offset like +10:00 records one numeric relationship to UTC, but it does not preserve that broader context.

Everything after & is temporal context, not necessarily a timezone reference. It may select a named timezone such as Australia/Melbourne, the resolving environment through exact lowercase local, a timescale such as TAI, a named place such as +/Antarctica/Elisabeth, or a geographic position such as -37.8142/144.9631.

WTC keeps two dimensions separate. Before &: the temporal value is unqualified, numeric-offset-qualified, or UTC-qualified. After &: the temporal context can be resolver-local, a named timezone, a timescale, or a geographic position. Parsers retain both; trusted consumers decide if and how to resolve them.

The suffix &local is late-bound: it asks a trusted resolver to supply the applicable local timezone rules. With an unqualified value, it creates resolver-local civil time. A named context such as &Australia/Melbourne supplies a fixed ruleset instead.

For example, 2027-01-31T23:59:59&local is not one global instant. It can mean just before Melbourne midnight for one subscriber and just before Brussels midnight for another—a context-indexed family of instants, or a rolling event across local contexts. The application must define whether local means the subscriber's current location, account timezone, or some other trusted context.

The value before & still matters. In 2027-01-31T23:59:59Z&local, Z says that the clock fields are UTC fields—not Melbourne civil fields waiting to be converted. The value identifies the same instant as 2027-01-31T23:59:59Z. The &local context can guide local projection or presentation of that fixed instant, but does not reinterpret it or make it float. AEON still preserves the two representations distinctly because only the WTC value carries that additional context.

The anchoring invariant gives the forms useful names. 2027-01-31T23:59:59&Australia/Melbourne is zone-anchored zoned civil time: keep the Melbourne clock fields if the rules change, allowing the derived instant to move. 2027-01-31T23:59:59Z&Australia/Melbourne is an instant-anchored zoned instant: keep the UTC instant, allowing its projected Melbourne clock time to move.

An explicit offset plus a zone carries both kinds of evidence. If later Melbourne rules disagree with 2027-01-31T23:59:59+11:00&Australia/Melbourne, a temporal-aware consumer should expose a conflict rather than silently changing either anchor. Pinning a timezone database version instead keeps resolution reproducible under that historical rule set.

The same anchoring principle applies across WTC. Civil time anchors calendar and clock fields. &local anchors interpretation to trusted resolver policy. A named timezone anchors it to a zone identity. An explicit offset anchors an exact instant to a numeric UTC relationship. Z anchors the UTC instant. Coordinates provide a geographic anchor, while UTC, TAI, UT1, TT, and GPS provide timescale anchors. These anchors can be composed, and incompatible claims must remain visible as conflicts.

### Civil time
- **Definition:** What does the clock say? A reading such as 8:30 PM is a floating civil time, not an instant. In WTC, those clock fields occur before &, while the suffix supplies context.

### Local time / zoned civil time
- **Definition:** Where is the clock? 8:30 PM in Melbourne pairs civil clock fields with timezone rules. A daylight-saving transition can produce one, multiple, or no matching instants, so call it a zoned instant only after successful resolution.

### Offset time
- **Definition:** How far is the clock from UTC? 8:30 PM +10:00 identifies an instant but does not preserve the location or the rules needed for future and historical local-time calculations.

### Universal time
- **Definition:** What exact moment is it? A complete value such as 2026-01-01T10:30:00Z identifies an instant on the UTC timeline. A time-only or reduced-precision value still lacks fields needed for one global instant.

### Geographic time
- **Definition:** Where exactly is the clock? A coordinate can support location-dependent work such as calculating the Sun's position for solar panels, but adds coordinate-system and geodetic context to timezone rules.

Time is partly political. Timezone and daylight-saving rules depend on historical context and can change. If a meeting is planned for 9:00 AM in Melbourne next month and the rules change, should it remain at 9:00 AM locally or remain attached to the global instant that was first calculated? Preserving the anchor lets a consumer answer from intent instead of guessing.

Timescales are an independent dimension. The temporal convention recognizes UTC, TAI, UT1, TT, and GPS and supplies a separate timescale attribute. Core already accepts their WTC spellings as named temporal contexts and preserves them without performing conversions.

Since implementation release 0.14.0, Core retains every authored fractional-second digit and trailing zero and preserves structurally plausible second 60 claims; 0.16.0 retains this behavior. The general-purpose schema applies to typed and untyped temporal literals, rejects second 60, and admits at most nine authored fractional digits. Leap tables, timezone rules, smears, and higher-precision domain policy remain downstream authority and schema concerns.

Reduced precision denotes a set of possible completions rather than implicit zeroes: 10:Z contains 10:30Z. Calendar-native values that do not fit Gregorian YYYY-MM-DD use calendarDate or calendarDateTime objects with an explicit calendar and monthCode. Core YYYY-MM-DD remains proleptic Gregorian and spans 0001 through 9999; year 0000 is no longer admitted.

```aeon
eventDate:date = 2026-05-05
localTime:time = 09:30
utcTime:time = 09:30Z
offsetTime:time = 09:30+10:00

published:datetime = 2026-05-05T09:30:00Z
precise:datetime = 2026-05-05T09:30:00.340000Z
leapClaim:datetime = 2016-12-31T23:59:60Z
localPublication:wtc = 2026-05-05T09:30:00Z&Australia/Melbourne
localOnly:wtc = 2026-05-05T09:30&local
subscriptionEnd:wtc = 2027-01-31T23:59:59&local
siteOpening:wtc = 2035-01-01T09:00&-36.7590183/144.2826718
measuredOpening:wtc = 2035-01-01T09:00+11:00&-36.7590183/144.2826718/213
researchStation:wtc = 2026-01-01T09:10:00+01:00&+/Antarctica/Elisabeth

coordinated:wtc = 2026-01-01T09:10:10&UTC
tai:wtc = 2026-01-01T09:10:10&TAI
earthRotation:wtc = 2026-01-01T09:10:10&UT1
terrestrial:wtc = 2026-01-01T09:10:10&TT
navigation:wtc = 2026-01-01T09:10:10&GPS

observation@{
  timescale:string = "TT"
}:datetime = 2026-01-01T09:10:10

hebrewDate:calendarDate = {
  calendar = "hebrew"
  year:int = 5779
  monthCode:string = "M05L"
  day:int = 23
}
```

<!-- SANSA -->

## Address literals let paths travel as data.

SANSA means Semantic Address NameSpace Abstraction. AEON reserves the sansa datatype for path and selector literals that a schema, tool, resolver, or external consumer can understand. In strict mode, SANSA address values use :sansa.

A sansa value is not the same thing as an AEON reference. The value stores an address. It does not resolve the address or expand selectors by itself.

```aeon
path:sansa = $.contact.name
contextual:sansa = ?.name
selector:sansa = $.inventory.items.*.sku
deep:sansa = $.inventory.**
attribute:sansa = $.reading.@.unit

copy:string = ~contact.name
pointer:object = ~>contact
```

[Learn SANSA syntax](/sansa-addressing.php)  
[Try playground](/sansa-playground.php)

<!-- Semantic Comments -->

## Comments can carry meaning without becoming data.

AEON separates ordinary data bindings from semantic comment channels. These channels can carry documentation, hints, annotations, and ecosystem signals while remaining outside the core assignment stream.

The safety rule is simple: comments can inform tools and readers, but they do not create bindings, change path identity, affect reference legality, or silently alter values.

```aeon
//! format:aeon
//# Billing fields shown on customer invoices.
//@ ui(section="billing", priority=1)
//? total should match the line-item sum after discounts.
//[ profile: "invoice.public.v1"
//{ structure: "totals are grouped by currency"
//( instruction: "consumer may calculate display totals"
invoice:object = {
  total:number = 7_000
}
```

### Host directive
- **Syntax:** `//!`
- **When to use:** Use at the file header for processor discovery or pre-parser routing. Outside that header slot, it is just a plain comment.

### Documentation
- **Syntax:** `//#`
- **When to use:** Use for reader-facing notes that explain a nearby binding, element, or container.

### Annotation
- **Syntax:** `//@`
- **When to use:** Use for machine-readable metadata that tools may understand, such as UI grouping, workflow state, or audience tags.

### Hint
- **Syntax:** `//?`
- **When to use:** Use for advisory guidance, editor hints, schema-profile notes, or human review reminders.

### Profile
- **Syntax:** `//[`
- **When to use:** Reserved for profile-related ecosystem notes. Use when the comment is about policy or profile-driven interpretation.

### Structure
- **Syntax:** `//{`
- **When to use:** Reserved for structural notes. Use when the comment is about grouping, shape, or document organization.

### Instruction
- **Syntax:** `//(`
- **When to use:** Reserved for instruction-like notes. Use for consumer-facing processing guidance that must not change core parsing.
View as HTML