I just had to solve this exact problem and Date::Business worked perfectly. See my test script below:
use strict;
use warnings;
use Business::Hours;
use Time::Local;
my $timeout_period_hours = 12;
my @tests = (
{ start_date => "2006-06-05 00:00:00",
+ # Monday
end_date => "2006-06-05 00:59:59",
+ # Monday
comment => "1 hour - in a business d
+ay" },
{ start_date => "2006-06-05 00:00:00",
+ # Monday
end_date => "2006-06-05 08:59:59",
+ # Monday
comment => "9 hours - in a business
+day" },
{ start_date => "2006-06-05 00:00:00",
+ # Monday
end_date => "2006-06-05 11:59:59",
+ # Monday
comment => "12 hours - in a business
+ day" },
{ start_date => "2006-06-05 00:00:00",
+ # Monday
end_date => "2006-06-05 12:59:59",
+ # Monday
comment => "13 hours - in a business
+ day" },
{ start_date => "2006-06-05 00:00:00",
+ # Monday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "1 day - 1 business day"
+},
{ start_date => "2006-06-04 00:00:00",
+ # Sun
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "2 days - 1 business day"
+ },
{ start_date => "2006-06-03 00:00:00",
+ # Sat
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "3 days - 1 business day"
+ },
{ start_date => "2006-06-02 00:00:00",
+ # Friday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "4 days - 2 business days
+" },
{ start_date => "2006-06-01 00:00:00",
+ # Thurs
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "5 days - 3 business days
+" },
{ start_date => "2006-05-31 00:00:00",
+ # Wed
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "6 days - 4 business days
+" },
{ start_date => "2006-05-30 00:00:00",
+ # Tuesday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "7 days - 5 business days
+" },
{ start_date => "2006-05-29 00:00:00",
+ # Monday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "8 days - 6 business days
+" },
{ start_date => "2006-05-28 00:00:00",
+ # Sunday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "9 days - 6 business days
+" },
{ start_date => "2006-05-27 00:00:00",
+ # Saturday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "10 days - 6 business day
+s" },
{ start_date => "2006-05-26 00:00:00",
+ # Friday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "11 days - 7 business day
+s" },
{ start_date => "2006-05-25 00:00:00",
+ # Thursday
end_date => "2006-06-05 23:59:59",
+ # Monday
comment => "12 days - 8 business day
+s" },
{ start_date => "2006-06-03 00:00:00",
+ # Saturday
end_date => "2006-06-04 23:59:59",
+ # Sunday
comment => "2 non-business days" },
{ start_date => "2006-06-04 00:00:00",
+ # Sunday
end_date => "2006-06-05 01:59:59",
+ # Monday
comment => "2 hours - 2 non-business
+ and 1 business days" },
{ start_date => "2006-06-03 00:00:00",
+ # Saturday
end_date => "2006-06-05 01:59:59",
+ # Monday
comment => "2 hours - 2 non-business
+ and 1 business days" },
# THESE ARE LARGE TIME SPAN TESTS
{ start_date => "2006-01-03 00:00:00",
+ # Tuesday
end_date => "2006-06-05 01:59:59",
+ # Monday
comment => "? hours - 2 non-business
+ and 1 business days" },
{ start_date => "2005-01-03 00:00:00",
+ # Tuesday
end_date => "2006-06-05 01:59:59",
+ # Monday
comment => "? hours - 2 non-business
+ and 1 business days" },
);
my $bus_hours = Business::Hours->new();
$bus_hours->business_hours(
0 => { Name => 'Sunday', Start => undef
+, End => undef},
1 => { Name => 'Monday', Start => '00:0
+0', End => '23:59'},
2 => { Name => 'Tuesday', Start => '00:0
+0', End => '23:59'},
3 => { Name => 'Wednesday', Start => '00:0
+0', End => '23:59'},
4 => { Name => 'Thursday', Start => '00:0
+0', End => '23:59'},
5 => { Name => 'Friday', Start => '00:0
+0', End => '23:59'},
6 => { Name => 'Saturday', Start => undef
+, End => undef}
);
my $test_counter = 0;
foreach (@tests) {
my $test = $_;
$test_counter++;
my $comment = $test->{comment} || '';
my $end_date = $test->{end_date};
my @end_date = split(/\D/, $end_date);
my $end_time = timelocal($end_date[5], $end_date[4], $end_
+date[3], $end_date[2], ($end_date[1] - 1), $end_date[0]);
my $start_date = $test->{start_date};
my @start_date = split(/\D/, $start_date);
my $start_time = timelocal($start_date[5], $start_date[4], $
+start_date[3], $start_date[2], ($start_date[1] - 1), $start_date[0]);
my $result = $bus_hours->for_timespan(Start => $start_ti
+me, End => $end_time);
#my $elements = $result->elements();
#my $elements_count = $result->cardinality();
#my $seconds = scalar(@$elements);
my $seconds = $result->cardinality();
my $hours = ($seconds / 60 / 60);
my $days = ($hours / 24);
#$hours = sprintf("%d", $hours);
#$days = sprintf("%d", $days);
#print "TEST[$test_counter]: [$start_date][$end_date]\n[$comment]\n
+DIFFERENCE SECONDS/HOURS: [$seconds][$hours]\n\n";
print "TEST[$test_counter]: [$comment]\nDATES: [$start_date] TO [$e
+nd_date]\nBUSINESS SECONDS/HOURS/DAYS: [$seconds][$hours][$days]\n\n"
+;
}
print "Done\n";