postgresqltypestimestamptimezone

Difference between timestamps with/without time zone in PostgreSQL


Are timestamp values stored differently in PostgreSQL when the data type is WITH TIME ZONE versus WITHOUT TIME ZONE? Can the differences be illustrated with simple test cases?


Solution

  • The differences are covered at the PostgreSQL documentation for date/time types. Yes, the treatment of TIME or TIMESTAMP differs between one WITH TIME ZONE or WITHOUT TIME ZONE. It doesn't affect how the values are stored; it affects how they are interpreted.

    The effects of time zones on these data types is covered specifically in the docs. The difference arises from what the system can reasonably know about the value:

    The behaviour differs depending on at least three factors:

    Here are examples covering the combinations of those factors:

    foo=> SET TIMEZONE TO 'Japan';
    SET
    foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
          timestamp      
    ---------------------
     2011-01-01 00:00:00
    (1 row)
    
    foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
          timestamptz       
    ------------------------
     2011-01-01 00:00:00+09
    (1 row)
    
    foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
          timestamp      
    ---------------------
     2011-01-01 00:00:00
    (1 row)
    
    foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
          timestamptz       
    ------------------------
     2011-01-01 06:00:00+09
    (1 row)
    
    foo=> SET TIMEZONE TO 'Australia/Melbourne';
    SET
    foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP;
          timestamp      
    ---------------------
     2011-01-01 00:00:00
    (1 row)
    
    foo=> SELECT '2011-01-01 00:00:00'::TIMESTAMP WITH TIME ZONE;
          timestamptz       
    ------------------------
     2011-01-01 00:00:00+11
    (1 row)
    
    foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP;
          timestamp      
    ---------------------
     2011-01-01 00:00:00
    (1 row)
    
    foo=> SELECT '2011-01-01 00:00:00+03'::TIMESTAMP WITH TIME ZONE;
          timestamptz       
    ------------------------
     2011-01-01 08:00:00+11
    (1 row)