A reader, June      13, 2024 - 1:46 pm UTC
 
 
Sorry my bad. You are right for second scenario it would be 0 hours 
 
A reader, June      13, 2024 - 1:48 pm UTC
 
 
Thanks and appreciated Chris. This would be a great help. I pick very lengthy solution and ran into performance issue. This is very straight forward and simple.  
June      14, 2024 - 3:25 am UTC 
 
glad we could help 
 
 
A reader, June      14, 2024 - 1:24 pm UTC
 
 
Hi Chris, I have another example where i am expecting 0.5 value. Could you please kindly help to check advise. 
ex: '11-MAY-2012 08:00:00' st, '11-MAY-2012 22:30:00' 
for above scenario, it should return 0.5 (30 mins) night hours 
but sql is giving 0 hours. 
June      14, 2024 - 4:58 pm UTC 
 
Like I said, this only handles whole hours. To handle fractions, you need to convert the values to minutes. e.g. 6am = 360 minutes. Then divide the working minutes by 60 to go back to hours 
 
 
A reader, June      17, 2024 - 8:09 am UTC
 
 
Thanks Chris. I have converted into mins and is work as expected.
with vals as (
  select '11-MAY-2012 08:00:00' st, '11-MAY-2012 22:45:00' en from dual 
  union all 
  select '11-MAY-2012 08:00:00' st, '11-MAY-2012 16:00:00' en from dual
  union all 
  select '11-MAY-2012 20:00:00' st, '12-MAY-2012 04:00:00' en from dual
), dts as (
select 
  to_date ( st, 'dd-mon-yyyy hh24:mi:ss' ) st_dt,
  to_date ( en, 'dd-mon-yyyy hh24:mi:ss' ) en_dt
from   vals
)
select dts.*,
 (CASE 
   WHEN EXTRACT ( DAY FROM st_dt ) = EXTRACT ( DAY FROM en_dt ) THEN 
   GREATEST ( (6*60) - (REGEXP_SUBSTR(to_char(st_dt,'hh24:mi'),'[^:]+',1,1)*60 + REGEXP_SUBSTR(to_char(st_dt,'hh24:mi'),'[^:]+',1,2)) , 0 ) +
   GREATEST ( (REGEXP_SUBSTR(to_char(en_dt,'hh24:mi'),'[^:]+',1,1)*60 + REGEXP_SUBSTR(to_char(en_dt,'hh24:mi'),'[^:]+',1,2)) - 22*60, 0 ) 
   ELSE 
    (24*60) - GREATEST ( (REGEXP_SUBSTR(to_char(st_dt,'hh24:mi'),'[^:]+',1,1)*60 + REGEXP_SUBSTR(to_char(st_dt,'hh24:mi'),'[^:]+',1,2)) , (22*60) ) +
    LEAST ( (REGEXP_SUBSTR(to_char(en_dt,'hh24:mi'),'[^:]+',1,1)*60 + REGEXP_SUBSTR(to_char(en_dt,'hh24:mi'),'[^:]+',1,2)), (6*60) ) 
   END)/60 night_time
from dts; 
June      18, 2024 - 4:15 am UTC 
 
nice work 
 
 
More a math problem than a programming one
mathguy, June      23, 2024 - 3:06 am UTC
 
 
There are several ways to solve this problem; in each case, once a mathematical solution has been chosen, writing the code is straightforward.
Here is how I would solve this. The formula for computing the number of night-shift hours between ST_DT and EN_DT is
8 * (trunc(en_dt + 2/24) - trunc(st_dt + 2/24))
+ least(8, 24 * (en_dt + 2/24 - trunc(en_dt + 2/24)))
- least(8, 24 * (st_dt + 2/24 - trunc(st_dt + 2/24)))
Adding 2/24 to the dates is a standard shift, to simplify the problem; the night shift is from 22:00 to 06:00, or - after adding two hours - it becomes from 00:00 to 08:00. (A cute, but not really helpful, way to think about this is that we convert the date-times to the time zone two hours ahead of us, to achieve this simplification).
Then the first term credits 8 hours for every full day from ST_DT to EN_DT, including ST_DT but excluding EN_DT. The second term adds the night-shift hours for EN_DT (the +2/24 trick makes this second term very simple), and similarly the last term adjusts for the night-shift hours before the time-of-day of ST_DT. 
June      24, 2024 - 4:55 am UTC 
 
nice stuff 
 
 
A reader, August    05, 2024 - 7:50 am UTC
 
 
Excellent, this had solved all the problems with night hours calculation. appreciated the kind help. 
August    06, 2024 - 12:27 am UTC 
 
glad we could help