In postgresql both timestamp and timestamptz are always stored in UTC, both types have the same 64-bit size.
The timezone can be set in the current session/connection:
set timezone TO 'UTC';
set timezone TO 'America/New_York';
set timezone TO 'EST5EDT';
set timezone TO 'CEST-1CET';
Postgresql defines time zones using
- name - with daylight saving if used in a given country
- abbreviation - only with or without daylight saving
- POSIX definition - daylight saving can be defined arbitrarily
My rules for working with timestamp in postgres:
- Set the UTC timezone in the session.
- Use type timestamp in the UTC timezone to store. Don't use timestamptz
- Use timezones definition according to POSIX or to name and use varchar(64) if need to store.
POSIX timezone format in Postgresql
- EST5EDT is the same as 'America/New_York'
- AAA5AAA,M3.2.0/2:00:00,M11.1.0/2:00:00 is the same as 'EST5EDT'
- CET-1CEST,M3.5.0,M10.5.0/3 is central european time with DST at full format
POSIX format description:
- EST5EDT and AAA5AAA - the number in the middle is the time offset relative to GMT, everything to the west is a positive number, everything to the east is a negative number (letters are most likely ignored, i don't know)
- ,.M3 third month (March)
- .2.0 second Sunday of the month (eg: .1.1 first Monday of the month)
- /2:00:00 time
- ,M11 eleventh month (November)
- .1.0 first Sunday of the month
- /2:00:00 is the time
Postgres timezone function
timestamp plus time offset EST5EDT
timezone('EST5EDT', timestamp) -- return type timestamptz
timestamptz minus time offset EST5EDT
timezone('EST5EDT', timestamptz) -- return type timestamp
Examples
Conversion timestamp to timestamptz
select
'By name - America/New_York' as timezone_format,
timezone('America/New_York', timestamp'2024-03-10 00:00:00') winter_dst,
timezone('America/New_York', timestamp'2024-03-11 00:00:00') summer_dst
union all
select
'by POSIX - EST5EDT' as timezone_format,
timezone('EST5EDT', timestamp'2024-03-10 00:00:00') winter_dst,
timezone('EST5EDT', timestamp'2024-03-11 00:00:00') summer_dst
union all
select
'by POSIX full - AAA5AAA,M3...' as timezone_format,
timezone('AAA5AAA,M3.2.0/2:00:00,M11.1.0/2:00:00', timestamp'2024-03-10 00:00:00') winter_dst,
timezone('AAA5AAA,M3.2.0/2:00:00,M11.1.0/2:00:00', timestamp'2024-03-11 00:00:00') summer_dst;
Result:
set timezone to 'UTC'
+--------------------------+--------------------------+--------------------------+
|timezone_format |winter_dst |summer_dst |
+--------------------------+--------------------------+--------------------------+
|By name - America/New_York|2024-03-10 05:00:00 +00:00|2024-03-11 04:00:00 +00:00|
|by POSIX - EST5EDT |2024-03-10 05:00:00 +00:00|2024-03-11 04:00:00 +00:00|
|by POSIX full - AAA5AAA,M3|2024-03-10 05:00:00 +00:00|2024-03-11 04:00:00 +00:00|
+--------------------------+--------------------------+--------------------------+
set timezone to 'EST5EDT';
+--------------------------+--------------------------+--------------------------+
|timezone_format |winter_dst |summer_dst |
+--------------------------+--------------------------+--------------------------+
|By name - America/New_York|2024-03-10 00:00:00 -05:00|2024-03-11 00:00:00 -04:00|
|by POSIX - EST5EDT |2024-03-10 00:00:00 -05:00|2024-03-11 00:00:00 -04:00|
|by POSIX full - AAA5AAA,M3|2024-03-10 00:00:00 -05:00|2024-03-11 00:00:00 -04:00|
+--------------------------+--------------------------+--------------------------+
Conversion timestamptz to timestamp
select
'by POSIX - use UTC' as timezone_format,
timezone('EST5EDT', timestamptz'2024-03-10 00:00:00Z') winter_dst,
timezone('EST5EDT', timestamptz'2024-03-11 00:00:00Z') summer_dst
union all
select
'by POSIX - use session timezone' as timezone_format,
timezone('EST5EDT', timestamptz'2024-03-10 00:00:00') winter_dst,
timezone('EST5EDT', timestamptz'2024-03-11 00:00:00') summer_dst;
set timezone TO 'UTC';
+-------------------------------+-------------------+-------------------+
|timezone_format |winter_dst |summer_dst |
+-------------------------------+-------------------+-------------------+
|by POSIX - use UTC |2024-03-09 19:00:00|2024-03-10 20:00:00|
|by POSIX - use session timezone|2024-03-09 19:00:00|2024-03-10 20:00:00|
+-------------------------------+-------------------+-------------------+
set timezone TO 'EST5EDT';
+-------------------------------+-------------------+-------------------+
|timezone_format |winter_dst |summer_dst |
+-------------------------------+-------------------+-------------------+
|by POSIX - use UTC |2024-03-09 19:00:00|2024-03-10 20:00:00|
|by POSIX - use session timezone|2024-03-10 00:00:00|2024-03-11 00:00:00|
+-------------------------------+-------------------+-------------------+
time stamp without timezone
– Aghast