AS400/DB2 - 将基于整数的日期和时间转换为时间戳?

AS400/DB2 - Converting integer based dates and times to a timestamp?

我有 4 个用户输入:startDateendDatestartTimeendTime

数据库中的日期和时间设置与我以前使用的任何设置都不同。日期是自 1900 年 12 月 31 日以来的天数。因此是一个整数。例如,2015 年 10 月 16 日,将表示为 41927。

时间采用 ISO 格式 - 没有小数点,因此也是整数。所以 08:00:00 将是 80000。19:00:00 将是 190000。它基本上是 hhmmss - 但有时你只有一个 h。

我正在尝试将日期和时间过滤到范围内。有一天,我只是在看时间,这很好用:

SELECT * FROM database WHERE day = 41927 AND time > startTime and time < endTime

如果您严格查看天数,它也有效:

SELECT * FROM database WHERE day > startDate AND day < endDate

当您需要两次查找两个日期之间的项目时就会出现问题,因为它会每天过滤掉这两个时间之间的所有内容。我知道有一种方法可以创建时间戳,但我正在努力使用两个整数将其放在查询中。

我有什么样的选择来解决这个问题?

您可以通过简单的算术来使用它:

select date('1900-12-31') + col days

不过,我怀疑真正的开始日期是1899-12-31。那是 Excel 使用的日期(所以第 1 天是 1900-01-01)。

编辑:

糟糕,漏掉了秒数。一种方法是:

select timestamp(date('1900-12-31') + coldays days) +
       (floor(coltime / 10000) * 60*60 +
        mod(floor(coltime / 100)) * 60
        mod(coltime, 100)
       ) seconds

当您有一个可行的答案(来自您的评论)时...

select  * from mytable
where CURRENT_TIMESTAMP 
         < timestamp(date('1900-12-31') + coldays days) 
              + (floor(coltime / 10000) * 60*60 
              + mod(floor(coltime / 100),100) * 60 mod(coltime, 100) ) 

您可能会发现它的性能不是很好,因为 WHERE 子句中列上的函数使用限制了标准索引的可用性。充其量,您将获得完整的索引扫描,而更糟糕的是,您将获得完整的 table 扫描。

两个选项
1) OS最近的一个版本(v6.1及更高版本)可以创建派生索引。

create index mytsidx on mytable 
  (timestamp(date('1900-12-31') + coldays days) 
             + (floor(coltime / 10000) * 60*60 
             + mod(floor(coltime / 100),100) * 60 mod(coltime, 100) )     
                seconds )

2) 在旧版本中,您需要将传入的时间戳转换成多个部分并进行比较:

   select * from mytable
     where (strdays < coldays 
             or strdays = coldays and strtime <= coltime)
        and (enddays > coldays
              or enddays = coldays and endtime >= coltime)

如果您选择选项 1,我建议您创建一个 UDF 来处理转换。

   create index mytsidx on mytable (CONVERT_TO_TS(coldays,coltime));

   select * from mytable
     where CONVERT_TO_TS(coldays,coltime)
              between start_ts and end_ts;