Earliest Timestamp supported in PostgreSQL

前端 未结 2 1380
时光取名叫无心
时光取名叫无心 2021-02-18 18:43

I work with different databases in a number of different time zones (and periods of time) and one thing that normally originates problems, is the date/time definition.

F

2条回答
  •  太阳男子
    2021-02-18 19:34

    The manual states the values as:

    • Low value: 4713 BC
    • High value: 294276 AD

    with the caveat, as Chris noted, that -infinity is also supported.

    See the note later in the same page in the manual; the above is only true if you are using integer timestamps, which are the default in all vaguely recent versions of PostgreSQL. If in doubt:

    SHOW integer_datetimes;
    

    will tell you. If you're using floating point datetimes instead, you get greater range and less (non-linear) precision. Any attempt to work out the minimum programatically must cope with that restriction.

    PostgreSQL does not just let you cast zero to a timestamp to get the minimum possible timestamp, nor would this make much sense if you were using floating point datetimes. You can use the julian date conversion function, but this gives you the epoch not the minimum time:

    postgres=> select to_timestamp(0);
          to_timestamp      
    ------------------------
     1970-01-01 08:00:00+08
    (1 row)
    

    because it accepts negative values. You'd think that giving it negative maxint would work, but the results are surprising to the point where I wonder if we've got a wrap-around bug lurking here:

    postgres=> select to_timestamp(-922337203685477);
              to_timestamp           
    ---------------------------------
     294247-01-10 12:00:54.775808+08
    (1 row)
    
    postgres=> select to_timestamp(-92233720368547);
              to_timestamp           
    ---------------------------------
     294247-01-10 12:00:54.775808+08
    (1 row)
    
    postgres=> select to_timestamp(-9223372036854);
             to_timestamp         
    ------------------------------
     294247-01-10 12:00:55.552+08
    (1 row)
    
    postgres=> select to_timestamp(-922337203685);
    ERROR:  timestamp out of range
    postgres=> select to_timestamp(-92233720368);
              to_timestamp           
    ---------------------------------
     0954-03-26 09:50:36+07:43:24 BC
    (1 row)
    
    postgres=> select to_timestamp(-9223372036);
             to_timestamp         
    ------------------------------
     1677-09-21 07:56:08+07:43:24
    (1 row)
    

    (Perhaps related to the fact that to_timestamp takes a double, even though timestamps are stored as integers these days?).

    I think it's possibly wisest to just let the timestamp range be any timestamp you don't get an error on. After all, the range of valid timestamps is not continuous:

    postgres=> SELECT TIMESTAMP '2000-02-29';
          timestamp      
    ---------------------
     2000-02-29 00:00:00
    (1 row)
    
    postgres=> SELECT TIMESTAMP '2001-02-29';
    ERROR:  date/time field value out of range: "2001-02-29"
    LINE 1: SELECT TIMESTAMP '2001-02-29';
    

    so you can't assume that just because a value is between two valid timestamps, it is its self valid.

提交回复
热议问题