Always Use TIMESTAMP WITH TIME ZONE
My recommendations for sane time zone management in PostgreSQL:
- Set
timezone = 'UTC'inpostgresq.conf. This makes UTC the default time zone for all connections. - Use
timestamp with time zone(akatimestamptz) andtime with time zone(akatimetz). They store values as UTC, but convert them on selection to whatever your time zone setting is. - Avoid
timestamp without time zone(akatimestamp) andtime without time zone(akatime). These columns do not know the time zone of a value, so different apps can insert values in different zones no one would ever know. - Always specify a time zone when inserting into a
timestamptzortimetzcolumn. Unless the zone is UTC. But even then, append a "Z" to your value: it's more explicit, and will keep you sane. - If you need to get
timestamptzortimetzvalues in a zone other than UTC, use theAT TIME ZONEexpression in your query. But be aware that the returned value will be atimestamportimevalue, with no more time zone. Good for reporting and queries, bad for storage. - If your app always needs data in some other time zone, have it
SET timezone = 'UTC'on connection. All values then retrieved from the database will be in the configured time zone. The app should still include the time zone in values sent to the database.
The one exception to the rule preferring timestamptz and timetz is a special case: partitioning. When partitioning data on timestamps, you must not use timestamptz. Why? Because almost no expression involving timestamptz comparison is immutable. Use one in a WHERE clause, and constraint exclusion may well be ignored and all partitions scanned. This is usually something you want to avoid.
So in this one case and only in this one case, use a timestamp without time zone column, but always insert data in UTC. This will keep things consistent with the timestamptz columns you have everywhere else in your database. Unless your app changes the value of the timestamp GUC when it connects, it can just assume that everything is always UTC, and should always send updates as UTC.
Backtalk