Когато извадите едно клеймо за време от друго, резултатът е вътрешен интервален тип данни, но можете да го третирате като „интервал ден до секунда“:
select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us;
HOURSPASSED
-------------------
+08 15:26:54.293892
„+08“ (в моята часова зона на сесията) е броят на дните, а не UTC отместване; това е стойността, защото когато преобразувате низ в дата или времеви печат и предоставяте само частта за час, частта за дата е по подразбиране на първия ден от текущия месец:
Стойностите за дата по подразбиране се определят, както следва:
- Годината е текущата година, както е върната от 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
Не можете директно да форматирате интервал, но можете да извлечете елементите на времето и да ги форматирате отделно и да ги свържете.
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
. (Повече за разликата тук.)