http://www.perlmonks.org?node_id=554890


in reply to Re: determining work hours between 2 dates
in thread determining work hours between 2 dates

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";