Reference · Precision

    Timestamp precision

    Epoch counters look simple until you wire seconds, milliseconds, and sub-second fields across services. This page summarizes units, portability, and the 32-bit cliff.

    Seconds vs milliseconds vs microseconds vs nanoseconds

    • Seconds — POSIX time_t, many JWT exp fields, cron.
    • Milliseconds — JavaScript Date, Kafka logical timestamps, browser performance.now() anchors.
    • Microseconds — MySQL DATETIME(6), some RPC frameworks (google.protobuf.Timestamp uses seconds + nanos).
    • Nanoseconds — Go, OpenTelemetry spans, kernel trace clocks; serialize as string or structured pair to avoid float rounding in JSON.

    Language-specific precision (typical)

    LanguagePrimary typeNotes
    JavaScript (ECMAScript)Number (IEEE 64-bit)ms typical; > 2^53 unsafe for integers
    Python 3float / int / datetimeμs in datetime; time.time() platform-dependent
    Gotime.Timens monotonic + wall
    Javajava.time.Instantns since epoch
    RustSystemTime / chronosub-ms OS-dependent
    C / POSIXtime_t / timespecoften s + ns field on modern libc

    The Year 2038 problem

    Signed 32-bit seconds overflow after 2147483647 (2038-01-19T03:14:07Z in many interpretations). Embedded systems, legacy file formats, and binary protocols still use 32-bit fields — migrate to 64-bit epoch seconds or fixed-point pairs with an explicit schema version.

    64-bit timestamp range

    64-bit signed seconds covers roughly ±292 billion years from the epoch; practically unlimited for civil time. Nanosecond fields in 64 bits require pairing with a seconds field (as in protobuf) rather than a single combined integer in JSON Number space — use strings or two columns.

    # Largest signed 32-bit Unix second (illustration)
    echo $((2147483647))
    
    # Prefer storing migration boundary as explicit type width in schema
    # created_at_s64 BIGINT  -- not INT
    Advertisement