UTC Timestamps

Timestamp is a UTC instant with nanosecond precision in the calendar range 0000-01-01..9999-12-31, without display-zone metadata. Default construction is invalid; invalid values compare equal and sort before valid values. Fixed arithmetic saturates at the calendar bounds, with checked variants and overflow predicates. Distance methods offer typed resolutions and checked invalid/overflow handling. See Working with UTC Timestamps for construction, comparison, text and binary exchange, epoch conversion, and arithmetic examples.

Serialization Contract

RawValue is std::pair<int32_t, int64_t>: days since the Core epoch and nanoseconds since UTC midnight. Valid fields lie in 0..3652424 and 0..86399999999999. Any negative field decodes to the canonical invalid state (-1, 0); oversized nonnegative fields fail validation. The binary encoding is exactly twelve big-endian bytes: signed 32-bit days followed by signed 64-bit nanoseconds. It excludes object padding; the invalid encoding is ffffffff0000000000000000. Bytewise order is chronological for valid encodings, but the invalid encoding sorts after them, unlike object comparison.

Canonical ISO output is YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ. Scalar epoch ticks support signed seconds, milliseconds, microseconds, and nanoseconds, truncating toward zero. Split seconds/fractions use floor seconds and a nonnegative nanosecond fraction. Every valid timestamp converts exactly to UTC DateTime; converting back discards display metadata.

Throwing timestamp factories report invalid numeric fields with OutOfRangeError and malformed binary representations with ParseError. Checked distances report invalid operands with OutOfRangeError. Optional and fallback variants retain their existing results.

Interface

class Timestamp

A compact UTC instant with nanosecond precision and no display-zone metadata.

See: UTC Timestamps

Public Types

using RawValue = std::pair<int32_t, int64_t>

The unbiased day count and nanoseconds since midnight.

Public Functions

constexpr Timestamp() noexcept = default

Create an invalid timestamp.

Timestamp(Date date, Time time) noexcept

Create a UTC instant from calendar fields; an invalid date produces an invalid timestamp.

Parameters:
  • date – The UTC date.

  • time – The UTC time.

constexpr std::strong_ordering operator<=>(const Timestamp&) const noexcept = default

Compare UTC instants; invalid timestamps sort first.

constexpr bool operator==(const Timestamp&) const noexcept = default

Test equality of UTC instants.

inline TimeDelta operator-(Timestamp other) const noexcept

Return the precise signed delta from the other timestamp to this one.

template<impl::TimestampAmount T>
inline Timestamp operator+(T amount) const noexcept

Return this timestamp with a fixed amount added.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

template<impl::TimestampAmount T>
inline Timestamp &operator+=(T amount) noexcept

Add a fixed amount in place.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

template<impl::TimestampAmount T>
inline Timestamp operator-(T amount) const noexcept

Return this timestamp with a fixed amount subtracted.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

template<impl::TimestampAmount T>
inline Timestamp &operator-=(T amount) noexcept

Subtract a fixed amount in place.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

inline constexpr bool isValid() const noexcept

Test whether this timestamp represents an instant.

inline constexpr bool isValidDateTime() const noexcept

Test whether this timestamp converts exactly to DateTime.

Date date() const noexcept

Return the UTC date, or an invalid date.

inline constexpr Days dateAsDays() const noexcept

Return days since the Core epoch, or minus one for invalid timestamps.

Time time() const noexcept

Return the UTC time, or midnight for invalid timestamps.

inline constexpr Nanoseconds timeAsNanoseconds() const noexcept

Return nanoseconds since midnight, or zero for invalid timestamps.

template<impl::TimestampAmount T>
bool wouldAddSaturate(T amount) const noexcept

Test whether applying a fixed amount would exceed the calendar range.

Parameters:

amount – The signed amount to add.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Returns:

Whether saturation would occur; false for invalid timestamps.

template<impl::TimestampAmount T>
Timestamp added(T amount) const noexcept

Return a shifted timestamp, saturating at the calendar boundaries.

Parameters:

amount – The signed amount to add.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Returns:

The shifted timestamp; invalid timestamps stay invalid.

template<impl::TimestampAmount T>
Timestamp addedOrThrow(T amount) const

Return an exactly shifted timestamp; invalid timestamps stay invalid.

Parameters:

amount – The signed amount to add.

Throws:

err::OverflowError – if the calendar range would be exceeded.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Returns:

The shifted timestamp.

template<impl::TimestampAmount T>
inline void add(T amount) noexcept

Apply saturating arithmetic in place.

Parameters:

amount – The signed amount to add.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

template<impl::TimestampAmount T>
inline void addOrThrow(T amount)

Apply exact arithmetic in place, leaving this timestamp unchanged on failure.

Parameters:

amount – The signed amount to add.

Throws:

err::OverflowError – if the calendar range would be exceeded.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

template<impl::TimestampAmount T>
bool wouldSubtractSaturate(T amount) const noexcept

Test whether applying a fixed amount would exceed the calendar range.

Parameters:

amount – The signed amount to subtract.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Returns:

Whether saturation would occur; false for invalid timestamps.

template<impl::TimestampAmount T>
Timestamp subtracted(T amount) const noexcept

Return a shifted timestamp, saturating at the calendar boundaries.

Parameters:

amount – The signed amount to subtract.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Returns:

The shifted timestamp; invalid timestamps stay invalid.

template<impl::TimestampAmount T>
Timestamp subtractedOrThrow(T amount) const

Return an exactly shifted timestamp; invalid timestamps stay invalid.

Parameters:

amount – The signed amount to subtract.

Throws:

err::OverflowError – if the calendar range would be exceeded.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Returns:

The shifted timestamp.

template<impl::TimestampAmount T>
inline void subtract(T amount) noexcept

Apply saturating arithmetic in place.

Parameters:

amount – The signed amount to subtract.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

template<impl::TimestampAmount T>
inline void subtractOrThrow(T amount)

Apply exact arithmetic in place, leaving this timestamp unchanged on failure.

Parameters:

amount – The signed amount to subtract.

Throws:

err::OverflowError – if the calendar range would be exceeded.

Template Parameters:

T – A fixed-unit amount, Duration or TimeDelta.

Seconds secondsTo(Timestamp other) const noexcept

Return the signed distance, truncated toward zero and saturated if necessary.

Parameters:

other – The target timestamp.

Returns:

The distance, or zero if either timestamp is invalid.

Seconds secondsToOrThrow(Timestamp other) const

Return the exact signed distance, truncated toward zero.

This timestamp must be valid.

Parameters:

other – The target timestamp. Must be valid.

Throws:
Returns:

The distance.

bool wouldSecondsToSaturate(Timestamp other) const noexcept

Test whether the distance would saturate; invalid operands return false.

Parameters:

other – The target timestamp.

Returns:

Whether the result exceeds its amount range.

Milliseconds millisecondsTo(Timestamp other) const noexcept

Return the signed distance, truncated toward zero and saturated if necessary.

Parameters:

other – The target timestamp.

Returns:

The distance, or zero if either timestamp is invalid.

Milliseconds millisecondsToOrThrow(Timestamp other) const

Return the exact signed distance, truncated toward zero.

This timestamp must be valid.

Parameters:

other – The target timestamp. Must be valid.

Throws:
Returns:

The distance.

bool wouldMillisecondsToSaturate(Timestamp other) const noexcept

Test whether the distance would saturate; invalid operands return false.

Parameters:

other – The target timestamp.

Returns:

Whether the result exceeds its amount range.

Microseconds microsecondsTo(Timestamp other) const noexcept

Return the signed distance, truncated toward zero and saturated if necessary.

Parameters:

other – The target timestamp.

Returns:

The distance, or zero if either timestamp is invalid.

Microseconds microsecondsToOrThrow(Timestamp other) const

Return the exact signed distance, truncated toward zero.

This timestamp must be valid.

Parameters:

other – The target timestamp. Must be valid.

Throws:
Returns:

The distance.

bool wouldMicrosecondsToSaturate(Timestamp other) const noexcept

Test whether the distance would saturate; invalid operands return false.

Parameters:

other – The target timestamp.

Returns:

Whether the result exceeds its amount range.

Nanoseconds nanosecondsTo(Timestamp other) const noexcept

Return the signed distance, truncated toward zero and saturated if necessary.

Parameters:

other – The target timestamp.

Returns:

The distance, or zero if either timestamp is invalid.

Nanoseconds nanosecondsToOrThrow(Timestamp other) const

Return the exact signed distance, truncated toward zero.

This timestamp must be valid.

Parameters:

other – The target timestamp. Must be valid.

Throws:
Returns:

The distance.

bool wouldNanosecondsToSaturate(Timestamp other) const noexcept

Test whether the distance would saturate; invalid operands return false.

Parameters:

other – The target timestamp.

Returns:

Whether the result exceeds its amount range.

Duration durationTo(Timestamp other) const noexcept

Return the signed distance, truncated toward zero and saturated if necessary.

Parameters:

other – The target timestamp.

Returns:

The distance, or zero if either timestamp is invalid.

Duration durationToOrThrow(Timestamp other) const

Return the exact signed distance, truncated toward zero.

This timestamp must be valid.

Parameters:

other – The target timestamp. Must be valid.

Throws:
Returns:

The distance.

bool wouldDurationToSaturate(Timestamp other) const noexcept

Test whether the distance would saturate; invalid operands return false.

Parameters:

other – The target timestamp.

Returns:

Whether the result exceeds its amount range.

TimeDelta timeDeltaTo(Timestamp other) const noexcept

Return the signed distance, truncated toward zero and saturated if necessary.

Parameters:

other – The target timestamp.

Returns:

The distance, or zero if either timestamp is invalid.

TimeDelta timeDeltaToOrThrow(Timestamp other) const

Return the exact signed distance, truncated toward zero.

This timestamp must be valid.

Parameters:

other – The target timestamp. Must be valid.

Throws:
Returns:

The distance.

bool wouldTimeDeltaToSaturate(Timestamp other) const noexcept

Test whether the distance would saturate; invalid operands return false.

Parameters:

other – The target timestamp.

Returns:

Whether the result exceeds its amount range.

inline constexpr RawValue toRawValue() const noexcept

Return the stored signed fields, including the canonical invalid state.

mem::ByteBlock toByteBlock() const

Serialize the signed day and nanoseconds as 12 big-endian bytes.

Returns:

The canonical binary representation, excluding object padding.

std::optional<DateTime> toDateTime() const noexcept

Convert to a UTC DateTime.

Returns:

The UTC instant, or no value for an invalid timestamp.

DateTime toDateTimeOrThrow() const

Convert to a UTC DateTime.

This timestamp must be valid.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

The UTC instant.

std::optional<text::String> toIsoString() const

Format the instant as YYYY-MM-DDTHH:MM:SS.nnnnnnnnnZ.

Returns:

The ISO text, or no value for an invalid timestamp.

text::String toIsoStringOrThrow() const

Format the instant with exactly nine fractional digits in UTC.

This timestamp must be valid.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

The ISO text.

text::String toString() const

Return canonical ISO text, or an empty string for an invalid timestamp.

template<impl::DateTimeTickUnit T>
std::optional<T> toTicks(TimeEpoch epoch = TimeEpoch::Core) const noexcept

Convert to signed ticks relative to a named epoch, truncating toward zero.

Template Parameters:

T – A seconds, milliseconds, microseconds or nanoseconds amount.

Parameters:

epoch – The reference epoch.

Returns:

The ticks, or no value if invalid or unrepresentable.

template<impl::DateTimeTickUnit T>
T toTicksOrThrow(TimeEpoch epoch = TimeEpoch::Core) const

Convert to signed ticks relative to a named epoch, truncating toward zero.

This timestamp must be valid and representable as ticks of T relative to epoch.

Template Parameters:

T – A supported fixed tick amount.

Parameters:

epoch – The reference epoch.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

The ticks.

auto toSecondsAndFractions(TimeEpoch epoch = TimeEpoch::Core) const noexcept -> std::optional<std::pair<Seconds, Nanoseconds>>

Split epoch-relative time into floor seconds and a nonnegative fraction.

Parameters:

epoch – The reference epoch.

Returns:

Seconds and nanoseconds, or no value for an invalid timestamp.

auto toSecondsAndFractionsOrThrow(TimeEpoch epoch = TimeEpoch::Core) const -> std::pair<Seconds, Nanoseconds>

Split epoch-relative time into floor seconds and a nonnegative fraction.

This timestamp must be valid.

Parameters:

epoch – The reference epoch.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

Seconds and nanoseconds.

std::time_t toTimeT() const noexcept

Convert to floor POSIX seconds, or minus one if invalid or outside the native range.

Public Static Functions

static Timestamp now() noexcept

Read the system wall clock directly; repeated or backwards values are possible.

Returns:

The current UTC instant, or invalid if outside the supported calendar range.

static Timestamp epoch(TimeEpoch epoch = TimeEpoch::Core) noexcept

Return a named epoch.

Parameters:

epoch – The epoch to return.

Returns:

The UTC epoch timestamp.

static inline constexpr Timestamp first() noexcept

Return 0000-01-01 midnight UTC.

static inline constexpr Timestamp last() noexcept

Return 9999-12-31 at the final nanosecond UTC.

static std::optional<Timestamp> fromRawValue(int32_t days, int64_t nanoseconds) noexcept

Create from unbiased fields; negative fields produce canonical invalid state.

Parameters:
  • days – The input days.

  • nanoseconds – The input nanoseconds.

Returns:

The timestamp, or no value on failure.

static Timestamp fromRawValueOrThrow(int32_t days, int64_t nanoseconds)

Create from unbiased fields; negative fields produce canonical invalid state.

Parameters:
  • days – The unbiased day count. Non-negative fields are checked against the supported calendar range.

  • nanoseconds – The nanoseconds since midnight. Non-negative fields are checked against the one-day limit.

Throws:

err::OutOfRangeError – If the fields exceed the calendar or time-of-day range.

Returns:

The timestamp.

static auto fromDaysAndNanoseconds(Days days, Nanoseconds nanoseconds) noexcept -> std::optional<Timestamp>

Create from unbiased day and nanosecond amounts.

Parameters:
  • days – The input days.

  • nanoseconds – The input nanoseconds.

Returns:

The timestamp, or no value on failure.

static Timestamp fromDaysAndNanosecondsOrThrow(Days days, Nanoseconds nanoseconds)

Create from unbiased day and nanosecond amounts.

Parameters:
  • days – The unbiased day count. Non-negative fields are checked against the supported calendar range.

  • nanoseconds – The nanoseconds since midnight. Non-negative fields are checked against the one-day limit.

Throws:

err::OutOfRangeError – If the fields exceed the calendar or time-of-day range.

Returns:

The timestamp.

static std::optional<Timestamp> fromByteBlock(const mem::ByteBlock &value) noexcept

Decode exactly 12 big-endian bytes.

Parameters:

value – The input value.

Returns:

The timestamp, or no value on failure.

static Timestamp fromByteBlockOrThrow(const mem::ByteBlock &value)

Decode exactly 12 big-endian bytes.

Parameters:

value – The encoded timestamp. Expected to contain exactly 12 big-endian bytes with representable fields.

Throws:

err::ParseError – If the input is not a canonical 12-byte timestamp.

Returns:

The timestamp.

static std::optional<Timestamp> fromDateTime(const DateTime &value) noexcept

Copy the UTC instant and discard display metadata.

Parameters:

value – The input value.

Returns:

The timestamp, or no value on failure.

static Timestamp fromDateTimeOrThrow(const DateTime &value)

Copy the UTC instant and discard display metadata.

Parameters:

value – The UTC date/time to copy. Must be convertible to the timestamp calendar range.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

The timestamp.

static std::optional<Timestamp> fromIsoString(const text::String &value)

Parse an ISO instant with seconds and an explicit zone offset.

Parameters:

value – The input value.

Returns:

The timestamp, or no value on failure.

static Timestamp fromIsoStringOrThrow(const text::String &value)

Parse an ISO instant with seconds and an explicit zone offset.

Parameters:

value – The input value.

Throws:

err::ParseError – if the input cannot be converted.

Returns:

The timestamp.

static inline std::optional<Timestamp> fromRawValue(RawValue value) noexcept

Create from a signed raw field pair.

Parameters:

value – The input fields.

Returns:

The timestamp, or no value on failure.

static inline Timestamp fromRawValueOrThrow(RawValue value)

Create from a signed raw field pair.

Parameters:

value – The signed raw fields. When both fields are non-negative, days must fit the supported calendar range and nanoseconds must be less than one day.

Throws:

err::OutOfRangeError – If the fields exceed the calendar or time-of-day range.

Returns:

The timestamp.

template<impl::DateTimeTickUnit T>
static auto fromTicks(T ticks, TimeEpoch epoch = TimeEpoch::Core) noexcept -> std::optional<Timestamp>

Create from signed ticks relative to a named epoch.

Template Parameters:

T – A supported fixed tick amount.

Parameters:
  • ticks – The signed tick count.

  • epoch – The reference epoch.

Returns:

The timestamp, or no value outside the calendar range.

template<impl::DateTimeTickUnit T>
static Timestamp fromTicksOrThrow(T ticks, TimeEpoch epoch = TimeEpoch::Core)

Create from signed ticks relative to a named epoch.

Template Parameters:

T – A supported fixed tick amount.

Parameters:
  • ticks – The signed tick count. Relative to epoch, must produce a result within the supported calendar range.

  • epoch – The reference epoch.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

The timestamp.

static auto fromTicks(Seconds seconds, Nanoseconds fractions, TimeEpoch epoch = TimeEpoch::Core) noexcept -> std::optional<Timestamp>

Create from floor seconds and a nonnegative nanosecond fraction.

Parameters:
  • seconds – The signed seconds relative to the epoch.

  • fractions – The fraction in 0..999999999.

  • epoch – The reference epoch.

Returns:

The timestamp, or no value on invalid input or range overflow.

static auto fromTicksOrThrow(Seconds seconds, Nanoseconds fractions, TimeEpoch epoch = TimeEpoch::Core) -> Timestamp

Create from floor seconds and a nonnegative nanosecond fraction.

Parameters:
  • seconds – The signed seconds relative to the epoch. Together with fractions, must produce a result within the supported calendar range.

  • fractions – The fraction in 0..999999999.

  • epoch – The reference epoch.

Throws:

err::OutOfRangeError – If the input is invalid or cannot be represented in the requested calendar or tick range.

Returns:

The timestamp.

static Timestamp fromTimeT(std::time_t value) noexcept

Create from signed native POSIX seconds.

Parameters:

value – The native seconds.

Returns:

The timestamp, or invalid outside the calendar range.