Sets, Recurrences, Public Holidays .. Business Days trouble

[email protected] (Rick Measham)
Newsgroups perl.datetime
Message-ID <[email protected]>
The aim is to work out N 'business days' from now.

Every one defines business days differently, but for me it's Monday to 
Friday skipping public holidays.

Step 1: Set of every day
Step 2: Complemented with weekends
Step 3: Complemented with public holidays

However, the code I've put together dies in rather nasty ways or runs 
really slowly (change the @events in the grep to @events[1,2])

If we forget about holidays, then it's nice and fast (though I'd prefer 
not to have to interate ...)

I'm guessing the speed decrease is due to the recurrence getting random 
holes (the public holidays) means we need to enumerate the entire set.

But for now, if someone could take a look at the code and see if you can 
work out why it dies, it would be much appreciated.

(note that $events[6] is the 28th of January and so it should be skipped 
.. but if you include '6' in the @events slice, you end up with it 
dieing on day 9)

Cheers!
Rick Measham
business_days.pl (application/x-perl, 1.4 KB)
#!/usr/bin/perl

use strict;
use warnings;

use DateTime;
use DateTime::Set;
use Data::ICal::DateTime;
use DateTime::Event::Recurrence;
use LWP::Simple;
use Data::Dumper;

my $daycount = 12;

my $min = DateTime->now->truncate( to => 'year' )->subtract( years => 1 );
my $max = $min->clone->add( years => 3 );

# Used a recurrence rather than this .. so we can set the start and end
#my $every_day = DateTime::Event::Recurrence->daily;

my $every_day = DateTime::Set->from_recurrence(
	recurrence => sub {
		return $_[0] if $_[0]->is_infinite;
		return $_[0]->truncate( to => 'day' )->add( days => 1 )
	},
	span => DateTime::Span->from_datetimes( start => $min, end => $max )
);

my $weekends  = DateTime::Event::Recurrence->weekly(
	days => [6,7]
);


my $public_holiday_ical = Data::ICal->new(
	# Melbourne public holidays
	data => get('http://www.google.com/calendar/ical/5be1qvd6221bpn0jknc1210qe4%40group.calendar.google.com/public/basic.ics')
);
my @events = $public_holiday_ical->events();

my $public_holidays = DateTime::Set->from_datetimes(
	dates => [
		map { $_->start }
		# We only want those that are actually public holidays
		grep { $_->property('description')->[0]->value eq 'Public Holiday' }
		@events
	]
);

my $business_days = $every_day->complement( $public_holidays );
$business_days = $business_days->complement( $weekends );

my $dt = DateTime->now;
for( 1 .. $daycount ){
	$dt = $business_days->next( $dt );
	print "$_ business days from now is $dt\n";
}
smime.p7s (application/x-pkcs7-signature, 3.2 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.