Saat Anda mengurangi satu stempel waktu dari yang lain, hasilnya adalah tipe data interval internal, tetapi Anda dapat memperlakukannya sebagai 'interval hari ke detik':
select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us;
HOURSPASSED
-------------------
+08 15:26:54.293892
'+08' (dalam zona waktu sesi saya) adalah jumlah hari, bukan offset UTC; itulah nilainya karena ketika Anda mengonversi string menjadi tanggal atau stempel waktu dan hanya memberikan bagian waktu, bagian tanggal default ke hari pertama bulan ini:
Nilai tanggal default ditentukan sebagai berikut:
- Tahun adalah tahun berjalan, seperti yang ditampilkan oleh SYSDATE.
- Bulan adalah bulan berjalan, seperti yang dikembalikan oleh SYSDATE.
- Hari itu 01 (hari pertama setiap bulan).
- Jam, menit, dan detik semuanya 0.
Nilai default ini digunakan dalam kueri yang meminta nilai tanggal di mana tanggal itu sendiri tidak ditentukan ...
Jadi saya benar-benar membandingkan:
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
Anda tidak dapat memformat interval secara langsung, tetapi Anda dapat mengekstrak elemen waktu dan memformatnya secara terpisah, dan menggabungkannya.
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
Menghitung interval yang sama berulang kali terlihat sedikit sia-sia dan sulit dikelola, jadi Anda dapat melakukannya dalam tampilan sebaris atau 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
Anda juga bisa menggunakan tanggal alih-alih cap waktu; pengurangan kemudian memberi Anda perbedaan sebagai angka, dengan hari utuh dan pecahan:
select current_date - to_date(us.STARTDATETIME, 'hh24:mi') as hourspassed
from random us;
HOURSPASSED
-----------
8.64368056
Cara paling sederhana untuk memformat adalah dengan menambahkannya ke waktu tengah malam yang diketahui dan kemudian menggunakan 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
Saya terjebak dengan current_date
sebagai yang paling cocok dengan localtimestamp
; Anda mungkin benar-benar menginginkan systimestamp
dan/atau sysdate
. (Lebih lanjut tentang perbedaannya di sini.)