minato_codec_datetime (minato v0.18.6)

View Source

Codecs for date, time, timestamp and timestamptz.

Internal to minato. The supported surface is minato_codec.

Wire formats

PostgreSQL has compiled with 64 bit integer timestamps since version 10, and the floating point build was removed, so the binary representations are:

  • date: int32 days relative to 2000-01-01.
  • time: int64 microseconds since midnight.
  • timestamp and timestamptz: int64 microseconds relative to 2000-01-01T00:00:00. timestamptz is always UTC on the wire; the server converts to and from the session time zone at the text boundary only.

The reserved values infinity and -infinity are the maximum and minimum of the signed integer for the type.

Erlang representation

date decodes to {Year, Month, Day}, the shape of calendar:date/0.

time, timestamp and timestamptz decode according to the datetime_format option:

  • datetime (the default) gives {Hour, Minute, Second} for time and {{Year, Month, Day}, {Hour, Minute, Second}} for the two timestamp types. Second is an integer, so sub-second precision is discarded. It is discarded by flooring, never by truncating towards zero, so the mapping stays monotonic across the epoch: 1999-12-31T23:59:59.5 decodes to 23:59:59 and not to 1999-12-31T23:59:60 or 2000-01-01T00:00:00.
  • microseconds is lossless. time gives an integer count of microseconds since midnight; timestamp and timestamptz give an integer count of microseconds since the Unix epoch, directly comparable with os:system_time(microsecond).

Encoding accepts either shape whatever the option says, because the option only governs what decoding produces. An integer passed to timestamp or timestamptz is read as microseconds since the Unix epoch, and an integer passed to time as microseconds since midnight.

infinity and neg_infinity are accepted and produced by date, timestamp and timestamptz in both directions.

Years are astronomical: year 0 is 1 BC. The binary format handles them, but PostgreSQL writes text dates before year 1 with a BC suffix in a different numbering, so decoding such a text value raises rather than guess.

Summary

Functions

The proleptic Gregorian date that is the given number of days from 1970-01-01.

Days from 1970-01-01 for a proleptic Gregorian date, using astronomical year numbering.

Decode Format wire bytes to a temporal value.

Encode a temporal value to Format wire bytes.

Functions

civil_from_days(Days)

-spec civil_from_days(integer()) -> {integer(), integer(), integer()}.

The proleptic Gregorian date that is the given number of days from 1970-01-01.

days_from_civil(Year, Month, Day)

-spec days_from_civil(integer(), integer(), integer()) -> integer().

Days from 1970-01-01 for a proleptic Gregorian date, using astronomical year numbering.

Exported because minato_codec_datetime owns the calendar arithmetic that date and the timestamp types share.

decode/4

-spec decode(date | time | timestamp | timestamptz,
             binary(),
             minato_codec:format(),
             minato_codec:opts()) ->
                minato_codec:value().

Decode Format wire bytes to a temporal value.

encode/4

-spec encode(date | time | timestamp | timestamptz, term(), minato_codec:format(), minato_codec:opts()) ->
                iodata().

Encode a temporal value to Format wire bytes.