aws/internal/codec/json_timestamp

JSON-side timestamp decoder. AWS protocol families disagree on the wire shape of @timestamp fields:

We never know which the server will send for a given field — fractional-second tests in particular surface Floats where the schema declares an Int member. Returning option.None on decode failure would mask data; instead we accept all three forms and coerce to Int (epoch seconds).

Types

Higher-precision timestamp value with nanosecond resolution. AWS services like CloudWatch, EventBridge, and metric APIs ship Float epoch-seconds wire values that carry sub-second precision; the existing Int decoder truncates them. Callers who need the precision use Timestamp end-to-end:

import aws/internal/codec/json_timestamp.{type Timestamp, Timestamp}

let t = Timestamp(seconds: 1700000000, nanoseconds: 123_000_000)
// ⇒ 2023-11-14T22:13:20.123 UTC

nanoseconds is bounded to [0, 999_999_999] by convention; callers normalising from a Float wire value get this for free (see decoder_precise).

pub type Timestamp {
  Timestamp(seconds: Int, nanoseconds: Int)
}

Constructors

  • Timestamp(seconds: Int, nanoseconds: Int)

Values

pub fn decoder() -> decode.Decoder(Int)

Decode Int | Float | String into epoch seconds. Falls back to 0 when none of the forms match, which matches gleam/dynamic’s default decode.failure payload style and lets the caller surface the decode failure via the standard Decoder machinery rather than crashing on bad data.

pub fn decoder_precise() -> decode.Decoder(Timestamp)

Decode an AWS timestamp wire value into a Timestamp that preserves sub-second precision when present.

  • IntTimestamp(seconds: n, nanoseconds: 0)
  • Float → fractional seconds extracted via floor + scaling to nanoseconds. Negative timestamps (pre-1970) handled by normalising the fractional remainder so nanoseconds is always in [0, 999_999_999].
  • String → ISO 8601 / HTTP-date, parsed with second-level precision today (fractional ISO timestamps would need an FFI extension; tracked separately).
pub fn encode_epoch_seconds(t: Timestamp) -> json.Json

Encode a Timestamp as a JSON epoch-seconds number. When nanoseconds == 0 we emit a JSON Int (1700000000) so the wire bytes match the existing json.int path the codegen uses for the Int API — flipping a member to precise must not perturb the wire form for callers who never set nanoseconds. When nanoseconds > 0 we emit a JSON Float (1700000000.5) so the fractional component reaches the server intact.

pub fn epoch_seconds_text(t: Timestamp) -> String

Render a Timestamp as a plain epoch-seconds integer string ("1700000000"). Used by URI / query / header / XML emitters when @timestampFormat("epoch-seconds") is in force — the wire form is the integer-as-decimal-digits, no fractional component.

pub fn format_http_date(seconds: Int) -> String

Tue, 29 Apr 2014 18:30:38 GMT. Used by @timestampFormat("http-date") body fields and headers.

pub fn format_http_date_precise(t: Timestamp) -> String

Format a Timestamp as HTTP-date (Tue, 29 Apr 2014 18:30:38 GMT). Same nanosecond caveat as format_iso8601_precise — HTTP-date is whole-second precision by definition.

pub fn format_iso8601(seconds: Int) -> String

2024-01-02T03:04:05Z. Inverse of parse_iso8601_ffi.

pub fn format_iso8601_precise(t: Timestamp) -> String

Format a Timestamp as ISO 8601 (2024-01-02T03:04:05Z). Wire-equivalent to format_iso8601(t.seconds) — sub-second precision is dropped because the underlying FFI doesn’t emit fractional seconds yet. Promoted to a distinct entry point so the codegen can call this from Timestamp-typed code paths without a redundant timestamp_to_int step.

pub fn int_to_timestamp(seconds: Int) -> Timestamp

Promote an Int epoch seconds value to a Timestamp with zero nanoseconds. Symmetric with timestamp_to_int.

pub fn parse_http_date(s: String) -> Result(Timestamp, Nil)

Parse an HTTP-date timestamp string (“Tue, 29 Apr 2014 18:30:38 GMT”) into a Timestamp. The default @timestampFormat for @httpHeader bindings per Smithy core — used by Last-Modified, Expires, Date, etc.

pub fn parse_iso8601(s: String) -> Result(Timestamp, Nil)

Parse an ISO 8601 timestamp string (“2024-01-02T03:04:05Z”) into a Timestamp at second precision. nanoseconds is always 0 until the FFI gains fractional-second support. Used by the header extractor for members carrying @timestampFormat("date-time").

pub fn timestamp_to_int(t: Timestamp) -> Int

Convert Timestamp back to integer epoch seconds, dropping the nanosecond component. Symmetric with int_to_timestamp and useful when callers want to bridge to the existing Int API.

Search Document