# We assume $dt1 and $dt2 are during working hours, and
# we assume that DST changes will never occur during working hours, so
# we can ignore time zones.
use DateTime::Format::RFC3339 qw( );
my $format = DateTime::Format::Strptime->new(
format => '%Y-%m-%dT%H:%M:%S',
time_zone => 'floating',
on_error => 'croak',
);
my $dt1 = $format->parse_datetime('2017-11-17T16:00:00');
my $dt2 = $format->parse_datetime('2017-11-22T17:10:00');
my $total = 0;
if (is_workday($dt1)) {
( my $eod = $dt1->clone() )
->set( hour => 17, minute => 30, second => 0, nanosecond => 0 );
$total += $eod->delta_ms($dt1)->in_units('seconds')
if $eod > $dt1;
}
if (is_workday($dt2)) {
( my $sod = $dt2->clone() )
->set( hour => 9, minute => 0, second => 0, nanosecond => 0 );
$total += $sod->delta_ms($dt2)->in_units('seconds')
if $sod < $dt2;
}
$dt1->truncate( to => 'day' );
$dt2->truncate( to => 'day' );
while (1) {
$dt1->add( days => 1 );
last if $dt1 >= $dt2;
next if !is_workday($dt1);
$total += 8.5 * 60;
}