- 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.
That sounds like the "proper" way.
A TIMESTAMP
column contains the time in UTC, but converts when storing and fetching, so that you can only see the value converted to your local time.
A DATETIME
column, on the other hand, is like taking a picture of a clock. There is no TZ conversion during store/fetch.
Since mysqldump is essentially a bunch of SELECTs
, and the reload is a bunch of INSERTs
, the data in the file looks like a picture of a clock. By using UTC during the fetch, the file will contain UTC time. By having that SET
, the INSERT
will, again, do no conversion to mess up the value.
Best Answer
A time zone name carries more information than an abbreviation or a simple time zone offset. 'UTC-6' is a "POSIX-style time zone specification" which is just an abbreviation plus offset.
The manual on Time Zones:
The difference you observe stems from another oddity. You have to use
+
instead of-
:The manual again:
However, even after fixing the offset error, both expressions are still not equivalent. Among other things, a time zone name like 'America/Chicago' also considers rules for daylight saving time (DST).
BTW, your expression can be simplified to:
But you probably want the time zone name, to be safe:
Related:
To address your second example:
Simplified, equivalent syntax:
The two instances of the literal
-1
have different meaning. The first offset is part of the*timetz*
literal signifying a location east of Greenwich (complying to the SQL standard). The second is a POSIX-style time zone specifications signifying an offset west of Greenwich. In the absence of a zone specification, UTC is assumed as base. See:Also note that the
AT TIME ZONE
construct returnstimetz
fortimetz
input. It just re-bases the time literal on a different offset. This is different from its use withtimestamp
/timestamptz
input, where the data type is also switched.But do not use the data type
timetz
(time with time zone
) at all. It's broken by design and only included in Postgres because it's part of standard SQL. It's use is explicitly discouraged. See: