Firebird数据库DOUBLE类型日期字段转TIMESTAMP的实现方法咨询
解决Firebird中DOUBLE类型存储的日期时间转TIMESTAMP问题
嗨,我之前刚好遇到过一模一样的问题!Firebird里用DOUBLE存的这种数值其实是Excel风格的日期序列号——整数部分是从1900年1月1日开始算的天数,小数部分是当天的时间占比(比如你给的43016.988360,43016是天数,0.988360就是当天接近24点的时间)。普通的CAST或CONVERT肯定不管用,因为Firebird根本不知道这是个日期,得用计算来转换。
直接查询转换的方法
你可以直接在SQL里通过日期加减来实现转换,注意要修正Excel的一个历史bug:
SELECT CAST( -- 从1900-01-01开始加上天数,减2是修正Excel的闰年错误 DATE '1900-01-01' + (:yourDoubleDateField - 2) -- 加上小数部分的时间(当天的占比) + (:yourDoubleDateField - FLOOR(:yourDoubleDateField)) AS TIMESTAMP ) AS convertedDatetime FROM yourTableName
为什么要减2?
Excel当年犯了个错:把1900年当成了闰年(实际上1900年不是闰年),所以它的日期计算里多算了一天(不存在的1900-02-29)。Firebird的日期计算是准确的,所以必须减2来修正这个偏差——如果你的数据里没有早于1900-03-01的日期,减1也能凑合用,但减2是通用的正确做法。
拿你给的43016.988360测试的话,转换后应该是2017-09-15 23:43:10左右,你可以自己跑一遍验证下。
更省心的方法:自定义函数
如果要多次用这个转换逻辑,不如在Firebird里建个自定义函数,以后直接调用就行:
CREATE OR ALTER FUNCTION ExcelDateToTimestamp(excelDate DOUBLE PRECISION) RETURNS TIMESTAMP AS BEGIN IF excelDate IS NULL THEN RETURN NULL; RETURN CAST( DATE '1900-01-01' + (excelDate - 2) + (excelDate - FLOOR(excelDate)) AS TIMESTAMP ); END;
之后查询就简单多了:
SELECT ExcelDateToTimestamp(yourDoubleDateField) AS convertedDatetime FROM yourTableName
快速验证结果
你可以用这个查询直接测试你的示例数值:
SELECT CAST( DATE '1900-01-01' + (43016.988360 - 2) + (43016.988360 - FLOOR(43016.988360)) AS TIMESTAMP ) AS testResult FROM RDB$DATABASE;
执行后就能看到转换后的正确日期时间了。
内容的提问来源于stack exchange,提问作者Anthony Doherty
相关产品推荐
相关产品推荐

