postgresql timezone conversion 'EST' != '-05'

前端 未结 2 582
故里飘歌
故里飘歌 2021-01-14 23:24

I am running PostgreSQL 9.6.6 on x86_64-pc-linux-gnu and my time zone is set to \'UTC\'.

Does anyone know why the results of the following SELECT statem

相关标签:
2条回答
  • 2021-01-14 23:56

    Okay I think I found an answer to my own question:

    According to the PostgreSQL docs, section 9.9.3 at the following link https://www.postgresql.org/docs/9.6/static/functions-datetime.html

    In these expressions, the desired time zone zone can be specified either as a text string (e.g., 'PST') or as an interval (e.g., INTERVAL '-08:00'). In the text case, a time zone name can be specified in any of the ways described in Section 8.5.3.

    So using the INTERVAL syntax, the following appears to work:

    SELECT timezone(INTERVAL '-05:00', '2017-12-21');
          timezone       
    ---------------------
    2017-12-20 19:00:00
    

    I think it is still curious, what exactly SELECT timezone('-05', '2017-12-21'); means, as the following also provides the expected result (with the addition of a TZ offset):

    SELECT timezone('-05', '2017-12-21'::timestamp);
            timezone        
    ------------------------
    2017-12-20 19:00:00+00
    
    0 讨论(0)
  • 2021-01-15 00:13

    https://www.postgresql.org/docs/current/static/view-pg-timezone-names.html

    The view pg_timezone_names provides a list of time zone names that are recognized by SET TIMEZONE

    and further:

    utc_offset interval Offset from UTC (positive means east of Greenwich)

    when you set timezone to 'EST' - you declare that your client is in EST time zone, thus returned time will be adjusted for your tz:

    t=# select '2017-12-21'::timestamptz;
          timestamptz
    ------------------------
     2017-12-21 00:00:00-05
    (1 row)
    

    the interval match utc_offset from pg_timezone_names and isequal -05, so it works as expected. (indeed in EST will be 5 hours less then UTC) same result if you set timezone to '-05'.

    Both -05 and EST give same result for SET TIMEZONE as described in docs.

    Now you answer reconciles with docs on using interval: https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-ZONECONVERT

    In these expressions, the desired time zone zone can be specified either as a text string (e.g., 'PST') or as an interval (e.g., INTERVAL '-08:00').

    following these rules it works as well:

    t=# select '2017-12-21'::timestamptz at time zone 'EST';
          timezone
    ---------------------
     2017-12-20 19:00:00
    (1 row)
    
    t=# select '2017-12-21'::timestamptz at time zone interval '-05:00';
          timezone
    ---------------------
     2017-12-20 19:00:00
    (1 row)
    

    but further, docs say:

    In the text case, a time zone name can be specified in any of the ways described in Section 8.5.3.

    which is https://www.postgresql.org/docs/current/static/datatype-datetime.html#DATATYPE-TIMEZONES

    PostgreSQL allows you to specify time zones in three different forms:

    • recognized time zone names are listed in the pg_timezone_names
    • recognized abbreviations are listed in the pg_timezone_abbrevs
    • POSIX-style time zone specifications of the form STDoffset or STDoffsetDST

    (formatting mine)

    and lastly:

    One should be wary that the POSIX-style time zone feature can lead to silently accepting bogus input...Another issue to keep in mind is that in POSIX time zone names, positive offsets are used for locations west of Greenwich. Everywhere else, PostgreSQL follows the ISO-8601 convention that positive timezone offsets are east of Greenwich.

    TL;DR

    So in short - when you define '-05' as text (not interval) input for timezone() function or AT TIME ZONE directive (effectively same) Postgres thinks this is an attempt to use POSIX style time zone and thus inverts sign, thus you get "opposite" result...

    a simple demonstration of this documented inversion:

    t=# select '2017-12-21'::timestamptz at time zone '05';
          timezone
    ---------------------
     2017-12-20 19:00:00
    (1 row)
    
    0 讨论(0)
提交回复
热议问题