Khi bạn trừ một dấu thời gian này cho một dấu thời gian khác, kết quả là một kiểu dữ liệu khoảng thời gian nội bộ, nhưng bạn có thể coi nó là 'khoảng thời gian từ ngày này sang giây khác':
select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us;
HOURSPASSED
-------------------
+08 15:26:54.293892
'+08' (trong múi giờ phiên của tôi) là số ngày, không phải là phần bù UTC; đó là giá trị bởi vì khi bạn chuyển đổi một chuỗi thành ngày hoặc dấu thời gian và chỉ cung cấp phần thời gian, phần ngày sẽ được mặc định là ngày đầu tiên của tháng hiện tại:
Các giá trị ngày mặc định được xác định như sau:
- Năm là năm hiện tại, được trả về bởi SYSDATE.
- Tháng là tháng hiện tại, được trả về bởi SYSDATE.
- Ngày là 01 (ngày đầu tiên của tháng).
- Giờ, phút và giây đều bằng 0.
Các giá trị mặc định này được sử dụng trong một truy vấn yêu cầu các giá trị ngày tháng mà chính ngày tháng đó không được chỉ định ...
Vì vậy, tôi thực sự đang so sánh:
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
Bạn không thể định dạng trực tiếp một khoảng thời gian, nhưng bạn có thể trích xuất các phần tử của thời gian và định dạng các phần tử đó một cách riêng biệt và nối chúng.
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
Việc tính toán lặp đi lặp lại cùng một khoảng thời gian có vẻ hơi lãng phí và khó quản lý, vì vậy bạn có thể làm điều đó trong chế độ xem nội tuyến hoặc 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
Bạn cũng có thể sử dụng ngày thay vì dấu thời gian; sau đó phép trừ cung cấp cho bạn sự khác biệt dưới dạng một số, với các ngày nguyên và phân số:
select current_date - to_date(us.STARTDATETIME, 'hh24:mi') as hourspassed
from random us;
HOURSPASSED
-----------
8.64368056
Cách đơn giản nhất để định dạng là thêm nó vào thời gian nửa đêm đã biết rồi sử dụng 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
Tôi bị mắc kẹt với current_date
là đối sánh gần nhất với localtimestamp
; bạn có thể thực sự muốn systimestamp
và / hoặc sysdate
. (Tìm hiểu thêm về sự khác biệt tại đây.)