Subject: | Fails to cope with hours that wrap midnight |
Date: | Mon, 12 Aug 2013 14:14:04 +0800 |
To: | bug-Business-Hours [...] rt.cpan.org |
From: | Craig Ringer <ringerc [...] ringerc.id.au> |
Hi
It looks like Business::Hours doesn't cope with hours that wrap over
midnight. So if you start at 04:00 and finish at 22:00, for example, it
will fail per the following test case.
The workaround is to define the period as from 00:00 to 23:59 with a
Break entry in the middle for the time that it's closed. I'm mostly
filing this report to make sure that others find it when looking for the
same info late.r
This test case demonstrates the problem when added to t/1-business-hours.t :
{
my $hours = Business::Hours->new();
# Define a shift that wraps midnight
$hours->business_hours(
1 => {
Name => 'Monday',
Start => '22:00',
End => '04:00',
}
);
# and see if we get the expected 6 hours in the week.
my $hours_span = $hours->for_timespan(Start => 0, End => ( (86400 *
7) - 1));
is(ref($hours_span), 'Set::IntSpan');
is(cardinality $hours_span, (6 * 60 * 60));
}
This fails with:
Set::IntSpan::_copy_run_list: Bad order 2: -208800--273601,396000-331199
when run under Set::IntSpan 1.19 and Business::Hours 0.11, both the
latest at the time of writing.
Because Business::Hours has no understanding of time zones, if you
operate 24x7 the only sane to specify shifts/operations half way around
the world is to have them wrap midnight.
The alternative is to define a 24-hour shift with a giant "break" in the
middle. This works, but is a bit uglier to generate and understand:
$hours->business_hours(
1 => {
Name => 'Monday',
Start => '00:00',
End => '23:59',
Breaks => [
{ Start => '04:00', End => '21:59' }
]
}
);
Since every Business::Hours period may be defined by a shift from 00:00
to 23:59 plus "breaks", a workaround is to just use breaks for
everything. If the shift doesn't split across midnight, you just create
two breaks, the morning pre-shift and the evening after-shift.
(In case you're wondering, it's the Australian hours of a support
operation that works 24x7, using UTC time to keep things sane).
Ideally you'd be able to write this with something like the (currently
invalid and unsupported, do NOT use as an example):
$hours->business_hours(
1 => {
Name => 'Monday',
TimeZone => 'Australia/Perth',
Start => '06:00',
End => '12:00',
}
);
or if you didn't want DST adjustment, a TZ offset. This isn't a feature
request, though, I'm sure you have no more time than I do to try to add
anything like that. I'm just writing up the problem and the simple
workaround for anyone else having issues later.
--
Craig Ringer