У меня вот что получилось. Таблица industrial_calendar имеет вид (id, date), где date — рабочие дни. Данные забираются с портала открытых данных РФ (data.gov.ru).
Код
with periods(id, start_time, stop_time) as (
values(1, '2019-03-29 07:00:00'::timestamp, '2019-04-08 14:00:00'::timestamp),
(2, '2019-04-10 07:00:00'::timestamp, '2019-04-10 20:00:00'::timestamp),
(3, '2019-04-11 12:00:00'::timestamp, '2019-04-12 16:07:12'::timestamp),
(4, '2018-12-28 12:00:00'::timestamp, '2019-01-16 16:00:00'::timestamp)
)
select p.id,
p.start_time as start_p,
p.stop_time as end_p,
sum((least((c.date || ' 19:00:00')::timestamp, p.stop_time) -
greatest((c.date || ' 10:00:00')::timestamp, p.start_time))::time) as work_time
from periods p
join industrial_calendar c on p.start_time::date <= c.date and p.stop_time::date >= c.date
group by p.id, p.start_time, p.stop_time