This is stated in a lot of places, but I think it worth mentioning always when we compare the timestamp with time zone
with timestamp without time zone
types: the timestamp WITH time zone
does not store the time zone information along with the timestamp. What it does is to store every data in UTC time zone, as stated in the docs:
For timestamp with time zone, the internally stored value is always in UTC (Universal Coordinated Time, traditionally known as Greenwich Mean Time, GMT). An input value that has an explicit time zone specified is converted to UTC using the appropriate offset for that time zone. If no time zone is stated in the input string, then it is assumed to be in the time zone indicated by the system's TimeZone parameter, and is converted to UTC using the offset for the timezone zone.
It is considered valid for some to use timestamp WITHOUT time zone
in situations where (1) everything is in the same timezone or (2) the application layer handles the time zone and just store everything in a certain time zone (usually UTC). But it is also considered an anti-pattern, simple because the correct solution for (1) is to configure the TimeZone setting to the given one timezone for the system and (2) is already solved, as PostgreSQL already stores everything on the same timezone (UTC).
Now, with those two down, I can came with only one good reason to use timestamp WITHOUT time zone
. That is when you want to store events in the future and that some kind of alert must be triggered when we got to that time. That could be good for timestamp WITH time zone
if, and only if, the rules defined by region's laws about time zone didn't ever change. The most common rule that changes is about the adoption or not of day light saving time (DST).
For example, imagine that you are at, let's say, 2013-06-15
(not yet in DST) schedule some event to happen at 2013-01-15 10:00
(which would be already in DST), and at 2013-06-15
your region was designated to adopt DST; but, some time after that, the government changed the rule and say your region will no longer use DST, and suddenly your scheduled time becomes 2013-01-15 11:00
(instead of 10:00
), that if you use timestamp WITH time zone
, and keep your TZ configurations up-to-date. Of course you may also notice that it is possible to treat such cases also with time zone, if you keep track of the rule changes in the regions/timezones of your interest, and update the affected records.
Worth mentioning that some regions does often change these rules (like at Brazil, some states - not the entire country - often change), but in most cases it changes it very earlier, so your users would be affected only by events scheduled very far from the current time.
With all that said, I only have one more suggestion. If you do have users, logs, or anything on different timezones, store the timezone they are coming from somewhere and choose and use timestamp with time zone
. That way you can (1) cross events happening closer to each other for different sources (independent of their timezones) and (2) show the original time (the clock time) the event has happened.
- what will be the effect of this on fields of type "timestamp with timezone"?
They're converted from their internal UTC representation to UTC-5 at the moment. They'll be converted using UTC+4 after. So applications will see a 9-hour time shift if they're ignoring the time zone. If they respect the time zone reported in the timestamp then there will be no effect.
One notable exception to this is where the timestamp is truncated to a date. The timestamp may fall on a different day in one time zone to in another time zone. Truncation of a timestamp with time zone to a date discards time zone information. So be cautious with date_trunc
, casts from timestamp with time zone
to date
, calls to extract
or date_part
, etc.
- what will be the effect of this on fields of type "timestamp without timezone"?
Nothing.
- what will happen to replication if we change the slave timezone?
Nothing. Replication is block level. It doesn't care about the timezone setting in the slightest.
This is just the same as changing TimeZone
in the master with a SET TimeZone
at the SQL level, or in the config file. So you can just try it with a standalone DB.
e.g.
test=> SHOW TimeZone;
TimeZone
----------------
Australia/West
(1 row)
test=> CREATE TABLE tztz(tstz timestamptz, ts timestamp);
CREATE TABLE
test=> INSERT INTO tztz(tstz, ts) values (current_timestamp, current_timestamp);
INSERT 0 1
test=> SELECT tstz, tstz::date, ts, ts::date FROM tztz;
tstz | tstz | ts | ts
-------------------------------+------------+----------------------------+------------
2015-08-02 20:48:56.664932+08 | 2015-08-02 | 2015-08-02 20:48:56.664932 | 2015-08-02
(1 row)
test=> SET TimeZone = UTC;
SET
test=> SELECT tstz, tstz::date, ts, ts::date FROM tztz;
tstz | tstz | ts | ts
-------------------------------+------------+----------------------------+------------
2015-08-02 12:48:56.664932+00 | 2015-08-02 | 2015-08-02 20:48:56.664932 | 2015-08-02
(1 row)
test=> SET TimeZone = 'UTC-4';
SET
test=> SELECT tstz, tstz::date, ts, ts::date FROM tztz;
tstz | tstz | ts | ts
-------------------------------+------------+----------------------------+------------
2015-08-02 16:48:56.664932+04 | 2015-08-02 | 2015-08-02 20:48:56.664932 | 2015-08-02
(1 row)
Note that in both cases the timestamp is the same, because 16:48 at UTC+04 is the same as 12:48 at UTC or 20:48 at UTC+8 (Australia/West).
However, when the timezone shift causes the timestamp to be in the prior or next day in that time zone...:
test=> SET TimeZone = 'UTC-12';
SET
test=> SELECT tstz, tstz::date, ts, ts::date FROM tztz;
tstz | tstz | ts | ts
-------------------------------+------------+----------------------------+------------
2015-08-03 00:48:56.664932+12 | 2015-08-03 | 2015-08-02 20:48:56.664932 | 2015-08-02
(1 row)
it's all fine with the timestamps still, but the timestamp with time zone
truncated to date
has moved to a different day.
If you're confused by the offsets seeming backwards that's because PostgreSQL respects the POSIX standard for time zone offsets which are, infuriatingly, backwards to the offsets most people use day to day.
Best Answer
There is no valid use case.
time with time zone
is broken by design and only included in Postgres since it's in the SQL standard. Don't use it.Time zones can have daylight saving time (DST) rules, which do not work with
timetz
at all.In fact, the use of
time with time zone
is officially discouraged: