sub wd { my ($min, $max) = @_ return DateTime::SpanSet->from_set_and_duration( set => DateTime::Set->from_recurrence( recurrence => sub { my ($dt) = @_; return $dt->truncate(to => 'day') ->add(days => ($min-$dt->wday()+7-1) % 7 + 1); }, ), days => $max-$min+1, ); } sub hr { my ($min, $max) = @_ return DateTime::SpanSet->from_set_and_duration( set => DateTime::Set->from_recurrence( recurrence => sub { my ($dt) = @_; $dt = $dt->add(days => 1) if $dt->hour() >= $min; return $dt->truncate(to => 'day')->set(hour => $min); }, ), hours => $max-$min+1, ) } # M-F, 9am to 5pm # wd {mo-fr} hr {9-16} my $sla_period = wd(1,5)->intersection(hr(9, 16));