数字到日期的转换(Oracle)

时间:2018-08-09 16:44:21

标签: oracle datetime math interpolation

我有一个与日期匹配的数字,我也不知道如何使用该日期计算数字,这是三个示例:

08/08/2018 12:23     73691437391180 
08/08/2018 12:32     73691437976165 
11/11/2015 14:41     73591349310000

如果我从第二个减去第二个,我得到的差是9.74975,它对应于经过的分钟(和秒?)?

谢谢!

PS:数据存储在Oracle数据库中。如果需要,可以生成更多示例。

1 个答案:

答案 0 :(得分:5)

有人梦想着这样做会很有趣。两个值之间的差异确实是毫秒,但不是明显的时代。

通过消除过程,它看起来像一个复合值,因为它不能可靠地匹配为单个值,例如除以60 * 60 * 24和其他形式。似乎基于0001-01-02 00:00:00 UTC的纪元时间。

前六位数字似乎是自公元1年1月2日(?)开始的天数。尝试一些可能的时代日期:

select date '2018-08-08' - date '0001-01-01' from dual;

DATE'2018-08-08'-DATE'0001-01-01'
---------------------------------
                           736915

这太巧了,不是巧合,但是要花一天时间,所以它实际上是基于0001-01-02的。

剩余的8位数字似乎是UTC午夜后的毫秒数-再次假设是从午夜开始已经很近了,但是一两个小时。因此,还有一个时区组件,它可能很有意义并与您的个人资料位置匹配。

这似乎至少对样本值有效:

with t (ts) as (
            select timestamp '2018-08-08 11:23:11.180' from dual
  union all select timestamp '2018-08-08 11:32:56.165' from dual
  union all select timestamp '2015-11-11 14:41:50.000' from dual
)
select ts,
  100000000 * extract(day from ts - timestamp '0001-01-02 01:00:00')
  + 3600000 * extract(hour from ts - timestamp '0001-01-02 01:00:00')
    + 60000 * extract(minute from ts - timestamp '0001-01-02 01:00:00')
     + 1000 * extract(second from ts - timestamp '0001-01-02 01:00:00') as n
from t;

             N TS                                         
-------------- -------------------------------------------
73691437391180 2018-08-08 12:23:11.180000000 EUROPE/VIENNA
73691437976165 2018-08-08 12:32:56.165000000 EUROPE/VIENNA
73591349310000 2015-11-11 14:41:50.000000000 EUROPE/VIENNA

或进行另一种转换,从时间戳而不是日期开始,因为涉及小数秒和时区:

with t (ts) as (
            select timestamp '2018-08-08 12:23:11.180 Europe/Vienna' from dual
  union all select timestamp '2018-08-08 12:32:56.165 Europe/Vienna' from dual
  union all select timestamp '2015-11-11 14:41:50.000 Europe/Vienna' from dual
)
select ts,
  100000000 * extract(day from ts - timestamp '0001-01-02 00:00:00 UTC')
  + 3600000 * extract(hour from ts - timestamp '0001-01-02 00:00:00 UTC')
    + 60000 * extract(minute from ts - timestamp '0001-01-02 00:00:00 UTC')
     + 1000 * extract(second from ts - timestamp '0001-01-02 00:00:00 UTC') as n
from t;

TS                                                       N
------------------------------------------- --------------
2018-08-08 12:23:11.180000000 EUROPE/VIENNA 73691437391180
2018-08-08 12:32:56.165000000 EUROPE/VIENNA 73691437976165
2015-11-11 14:41:50.000000000 EUROPE/VIENNA 73591349310000

有点...不寻常。

对于时间戳到数字的转换,起始值也可以是纯时间戳;只要您的会话在该时区,通过隐式转换将获得相同的结果。