将Double Precision列转换为Date时的舍入伪像

时间:2019-02-07 13:52:17

标签: firebird

在表中,日期被保存为数据类型DOUBLE PRECISION。尝试将其转换为日期格式,但时间戳大于12PM时会出现不正确的日期(即,如果时间戳大于或等于12:00:00.000,则给出第二天的日期)

这是我尝试过的

  1. dateColumn + CAST(日期为“ 30.12.1899”)
  2. DATE'1899-12-30'+ dateColumn

示例

SELECT  po.DELIVERYDATE as DOUBLE_FORMAT, 
        po.DELIVERYDATE + CAST ('30.12.1899' AS TIMESTAMP) as DATE_TIMESTAMP_FORMAT, 
        po.DELIVERYDATE + CAST ('30.12.1899' AS DATE) as DATE_FORMAT_1,
        DATE'1899-12-30' + po.DELIVERYDATE   as DATE_FORMAT_2
FROM    PURCHASE_ORDER po

结果

DOUBLE_FORMAT    DATE_TIMESTAMP_FORMAT      DATE_FORMAT_1   DATE_FORMAT_2
-------------    ------------------------   -------------   -------------
41485.421586     30.07.2013, 10:07:05.000   30.07.2013      30.07.2013
41488.487419     02.08.2013, 11:41:53.000   02.08.2013      02.08.2013
41488.489792     02.08.2013, 11:45:18.000   02.08.2013      02.08.2013
41506.630035     20.08.2013, 15:07:15.000   21.08.2013      21.08.2013 //<-- Incorrect
41516.514479     30.08.2013, 12:20:51.000   31.08.2013      31.08.2013 //<-- Incorrect
41521.402963     04.09.2013, 09:40:16.000   04.09.2013      04.09.2013
41520.511030     03.09.2013, 12:15:53.000   04.09.2013      04.09.2013 //<-- Incorrect

1 个答案:

答案 0 :(得分:1)

这是算术运算:将浮点四舍五入为整数时,然后将2.5舍入为3而不是2。

所以你必须

  • 或者,按照您想要的之前偏移基准日期的方向,将float显式转换为整数
  • 或者,因为您的数据既是日期又是时间-请先将其转换为TIMESTAMP,然后再将 转换为DATE

示例:

select
  41516.514479,                                       -- 41516,514479
  cast( 41516.514479 as integer ),                    -- 41517
  round( 41516.514479 ),                              -- 41517   
  41516.514479 + DATE '1899-12-30',                   -- 31.08.2013
  floor( 41516.514479 ),                              -- 41516   
  floor( 41516.514479 ) + DATE '1899-12-30',          -- 30.08.2013
  41516.514479 + timestamp '1899-12-30',              -- 12:20 30.08.2013
  cast(41516.514479 + timestamp '1899-12-30' as DATE) -- 30.08.2013
from rdb$database