Если вы открыты для использования только BQ, рассмотрите следующий фрагмент в BigQuery Standard SQL:
with data as (
select 1 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 1 day) as ts2 union all
select 2 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 2 day) as ts2 union all
select 3 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 3 day) as ts2 union all
select 4 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 4 day) as ts2 union all
select 5 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 5 day) as ts2 union all
select 6 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 6 day) as ts2 union all
select 7 as id, current_timestamp() as ts1, timestamp_add(current_timestamp(), interval 7 day) as ts2
),
temp as (
select *
from data, unnest(generate_timestamp_array(timestamp_trunc(ts1,day),timestamp_trunc(ts2,day),interval 1 day)) calendar
)
select
id, ts1, ts2,
sum(
case
-- Get # of Seconds on First Day from ts1 to 5:00PM
when timestamp_trunc(ts1,day) = timestamp_trunc(calendar,day)
then greatest(timestamp_diff(timestamp_add(calendar,interval 17 hour),ts1,second),0)
-- Get # of Seconds on Last Day from 8:00AM to ts2
when timestamp_trunc(ts2,day) = timestamp_trunc(calendar,day)
then greatest(timestamp_diff(ts2,timestamp_add(calendar, interval 8 hour),second),0)
-- Otherwise it is a full 8 hour day
else 8*60*60
end
) as working_seconds
from temp
where extract(dayofweek from calendar) not in (7,1) -- Exclude Saturday and Sunday
group by 1,2,3