When reading the PostreSQL (13) documentation, I came across this page, which lists the storage sizes of different datetime types.
Inter alia it states:
Name Storage Size Description Low Value High Value Resolution
---- ------------ ----------- --------- ---------- ----------
timestamp without time zone 8 bytes both date and time (no time zone) 4713 BC 294276 AD 1 microsecond
timestamp with time zone 8 bytes both date and time, with time zone 4713 BC 294276 AD 1 microsecond
time with time zone 12 bytes time of day (no date), with time zone 00:00:00+1559 24:00:00-1559 1 microsecond
I can understand timestamp without time zone: There are roughly (4713 + 294276) * 365 * 24 * 60 * 60 * 1000000 microseconds between low and high value. (Not accounting for calender changes and such). This amounts to roughly 2^63 values and those can be stored in 8 bytes.
However, timestamp with timezone has the same range and resolution and can additonally store the time zone information. If we already use 63 bits for the values there is only one bit left, which cannot be enough to store the timezone, so the internal storage must work somehow different.
Even stranger, while timestamps use only 8 bytes, time with time zone needs 12 bytes, although it has the same resolution and a much smaller range of allowed values.
Thus my question: How does the internal storage of these types in PostgreSQL work?
time with time zoneshould not be used