php-dextrin

Temporal
in package

FinalYes

DXN's dates and times as text (DXN.md §1.2, §1.5; Jan, 2026-10-20): the ISO 8601 strings under `@date`, `@time`, `@datetime`, `@local-datetime` and `@duration`, read and written in one place so the parser, the printer and the canonical form never drift apart.

Times keep up to nine fraction digits, nanoseconds; written, the fraction loses its trailing zeros, and a datetime at offset zero is written Z. A datetime's offset is Z or ±HH:MM, and -00:00 ("offset unknown") is refused -- a value with no offset is a local date-time. Every parse throws \InvalidArgumentException for text that is not the form its tag names, which the parser turns into a syntax error at the tag.

Table of Contents

Constants

DATE_RE  : mixed = '/^(\d{4})-(\d{2})-(\d{2})$/D'
DATETIME_RE  : mixed = '/^(\d{4}-\d{2}-\d{2})T([^Z+-]+)(Z|[+-]\d{2}:\d...
DURATION_RE  : mixed = '/^P(?:(-?\d+)Y)?(?:(-?\d+)M)?(?:(-?\d+)W)?(?:(...
LOCAL_RE  : mixed = '/^(\d{4}-\d{2}-\d{2})T(.+)$/D'
TIME_RE  : mixed = '/^(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?$/D'

Methods

formatDate()  : string
formatDateTime()  : string
The wall clock at its offset, then `Z` for zero or `±HH:MM`.
formatDuration()  : string
`P...`: the fields in DXN.md §2.3's order, absent ones left out, `PT0S` when none.
formatLocalDateTime()  : string
`YYYY-MM-DDTHH:MM:SS` and the fraction.
formatTime()  : string
`HH:MM:SS`, then the fraction with trailing zeros removed, or nothing when it is zero (DXN.md §1.5).
offsetName()  : string
An offset in minutes as a datetime writes it: `Z`, or `±HH:MM`.
parseDate()  : DXNDate
`YYYY-MM-DD`.
parseDateTime()  : DXNDateTime
A date, `T`, a time, and an offset, `Z` or `±HH:MM`.
parseDuration()  : DXNDuration
`P...`, ISO 8601, each field's sign its own, the seconds with up to nine fraction digits.
parseLocalDateTime()  : DXNLocalDateTime
A date, `T` and a time, no offset.
parseTime()  : DXNTime
`HH:MM:SS`, then up to nine fraction digits.
tagged()  : array{0: string, 1: string}|null
A date, time, datetime, local date-time or duration as its tag and ISO 8601 text, `['date', '2026-10-20']`, or null for any other value -- what the printer and the canonical form both write. A native `\DateTimeInterface` is the datetime it always means.
__construct()  : mixed
formatLocalNanos()  : string
fraction()  : string
`.` and the nanoseconds as nine digits less their trailing zeros, or nothing for none.
intOrNull()  : int|null
offsetMinutes()  : int
`Z` is zero; `-00:00`, an unknown offset, is refused.
part()  : string

Constants

DATE_RE

private mixed DATE_RE = '/^(\d{4})-(\d{2})-(\d{2})$/D'

DATETIME_RE

private mixed DATETIME_RE = '/^(\d{4}-\d{2}-\d{2})T([^Z+-]+)(Z|[+-]\d{2}:\d{2})$/D'

DURATION_RE

private mixed DURATION_RE = '/^P(?:(-?\d+)Y)?(?:(-?\d+)M)?(?:(-?\d+)W)?(?:(-?\d+)D)?(?:T(?:(-?\d+)H)?(?:(-?\d+)M)?(?:(-?)(\d+)(?:\.(\d{1,9}))?S)?)?$/D'

LOCAL_RE

private mixed LOCAL_RE = '/^(\d{4}-\d{2}-\d{2})T(.+)$/D'

TIME_RE

private mixed TIME_RE = '/^(\d{2}):(\d{2}):(\d{2})(?:\.(\d{1,9}))?$/D'

Methods

formatDate()

public static formatDate(DXNDate $date) : string
Parameters
$date : DXNDate
Return values
string

formatDateTime()

The wall clock at its offset, then `Z` for zero or `±HH:MM`.

public static formatDateTime(DXNDateTime $dt) : string
Parameters
$dt : DXNDateTime
Return values
string

formatDuration()

`P...`: the fields in DXN.md §2.3's order, absent ones left out, `PT0S` when none.

public static formatDuration(DXNDuration $d) : string
Parameters
$d : DXNDuration
Return values
string

formatTime()

`HH:MM:SS`, then the fraction with trailing zeros removed, or nothing when it is zero (DXN.md §1.5).

public static formatTime(DXNTime $time) : string
Parameters
$time : DXNTime
Return values
string

offsetName()

An offset in minutes as a datetime writes it: `Z`, or `±HH:MM`.

public static offsetName(int $minutes) : string
Parameters
$minutes : int
Return values
string

parseDate()

`YYYY-MM-DD`.

public static parseDate(string $text) : DXNDate
Parameters
$text : string
Tags
throws
InvalidArgumentException

for any other text, or a date that is none.

Return values
DXNDate

parseDateTime()

A date, `T`, a time, and an offset, `Z` or `±HH:MM`.

public static parseDateTime(string $text) : DXNDateTime
Parameters
$text : string
Tags
throws
InvalidArgumentException

for any other text, -00:00, or an instant 64 bits cannot hold.

Return values
DXNDateTime

parseDuration()

`P...`, ISO 8601, each field's sign its own, the seconds with up to nine fraction digits.

public static parseDuration(string $text) : DXNDuration
Parameters
$text : string
Tags
throws
InvalidArgumentException

for any other text, or no field at all.

Return values
DXNDuration

parseLocalDateTime()

A date, `T` and a time, no offset.

public static parseLocalDateTime(string $text) : DXNLocalDateTime
Parameters
$text : string
Tags
throws
InvalidArgumentException

for any other text, or a value 64 bits cannot hold.

Return values
DXNLocalDateTime

parseTime()

`HH:MM:SS`, then up to nine fraction digits.

public static parseTime(string $text) : DXNTime
Parameters
$text : string
Tags
throws
InvalidArgumentException

for any other text, or a time that is none.

Return values
DXNTime

tagged()

A date, time, datetime, local date-time or duration as its tag and ISO 8601 text, `['date', '2026-10-20']`, or null for any other value -- what the printer and the canonical form both write. A native `\DateTimeInterface` is the datetime it always means.

public static tagged(mixed $value) : array{0: string, 1: string}|null
Parameters
$value : mixed
Return values
array{0: string, 1: string}|null

__construct()

private __construct() : mixed

formatLocalNanos()

private static formatLocalNanos(int $local) : string
Parameters
$local : int
Return values
string

fraction()

`.` and the nanoseconds as nine digits less their trailing zeros, or nothing for none.

private static fraction(int $nanos) : string
Parameters
$nanos : int
Return values
string

intOrNull()

private static intOrNull(string $s) : int|null
Parameters
$s : string
Return values
int|null

offsetMinutes()

`Z` is zero; `-00:00`, an unknown offset, is refused.

private static offsetMinutes(string $offset, string $text) : int
Parameters
$offset : string
$text : string
Return values
int

part()

private static part(int|null $n, string $unit) : string
Parameters
$n : int|null
$unit : string
Return values
string
On this page

Search results