当你subtract one timestamp from another时,结果是一个内部区间数据类型,但你可以把它当成'interval day to second':
select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us;
HOURSPASSED
-------------------
+08 15:26:54.293892
“+08”(在我的会话时区中)是天数,而不是 UTC 偏移量;这是因为当您将字符串转换为日期或时间戳并仅提供时间部分时,日期部分defaults to the first day of the current month:
默认日期值确定如下:
- 年份是当前年份,由 SYSDATE 返回。
- 月份是当前月份,由 SYSDATE 返回。
- 当天是 01(每月的第一天)。
- 时、分、秒均为0。
这些默认值用于请求日期值的查询中,其中日期本身未指定...
所以我真的在比较:
select localtimestamp, to_timestamp(us.STARTDATETIME,'hh24:mi:ss')
from random us;
LOCALTIMESTAMP TO_TIMESTAMP(US.STARTDATET
-------------------------- --------------------------
2017-08-09 23:26:54.293892 2017-08-01 08:00:00.000000
你不能直接格式化一个区间,但是你可以extract时间的元素,分别格式化,然后串联起来。
select to_char(extract(hour from (localtimestamp
- to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
||':'|| to_char(extract(minute from (localtimestamp
- to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
||':'|| to_char(extract(second from (localtimestamp
- to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
as hourspassed
from random us;
HOURSPASSED
-----------
15:26:54
重复计算相同的间隔看起来有点浪费且难以管理,因此您可以在内联视图或 CTE 中执行此操作:
with cte (diff) as (
select localtimestamp - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss')
from random us
)
select to_char(extract(hour from diff), 'FM00')
||':'|| to_char(extract(minute from diff), 'FM00')
||':'|| to_char(extract(second from diff), 'FM00')
as hourspassed
from cte;
HOURSPASSED
-----------
15:26:54
您也可以使用日期而不是时间戳;减法然后将差值作为数字给出,包括整数天和小数天:
select current_date - to_date(us.STARTDATETIME, 'hh24:mi') as hourspassed
from random us;
HOURSPASSED
-----------
8.64368056
最简单的格式化方法是将其添加到已知的午夜时间,然后使用to_char():
select to_char(date '1970-01-01'
+ (current_date - to_date(us.STARTDATETIME, 'hh24:mi')),
'HH24:MI:SS') as hourspassed
from random us;
HOURSPAS
--------
15:26:54
我坚持使用 current_date 作为最接近 localtimestamp 的匹配项;您实际上可能想要systimestamp 和/或sysdate。 (更多关于区别here。)