R
robic0
Bart said:(e-mail address removed) wrote:It does. I prefer Date::Calc rather than the slower Date::Manip (that
is, if I have the choice).
Here is a variation I wrote - most of it mine, except for the
outsourced Day_Of_Week function from Date::Calc . It could use some
optimization perhaps (like looping over price/[date ranges] first, to
eliminate some redundant calculations in "InRange" ). Some of the
variables exist only for human legibility. Not sure how it compares to
the previous ones, in terms of efficiency (would be interested in
comments on that, or on anything else).
andrew
#!/usr/bin/perl
use strict;
use Date::Calc qw(Day_of_Week);
my @wdaynames=qw(sun mon tue wed thu fri sat);
my %a2n_wd=map { $wdaynames[$_], $_ } (0..$#wdaynames);
my @ss_specs=([0,4], [4,2], [6,2]); # substring specs
my (%prices, %newprices);
sub InRange {
my ($date,$range)=@_;
my ($smd,$emd,$swd_name,$ewd_name)=
($range=~/(\d{8})\-(\d{8})\|([a-z]{3})\-([a-z]{3})/i);
my ($swd,$ewd) = map { $a2n_wd{lc $_} } ($swd_name,$ewd_name);
my %applicable_weekdays=map {$_%7, 1} ($swd..( $ewd+($ewd>$swd ? 0
: 7)-1));
my $dow=&Day_of_Week(map {substr($date, $ss_specs[$_][0],
$ss_specs[$_][1])} (0..2));
return 0 unless ($applicable_weekdays{$dow % 7});
( ( $date >= $smd ) && ( $date <= $emd ) );
}
#---------------- data --------------------
my @dates = qw(20051230 20051231 20060101 20060102 20060103);
%prices = (
'20051010-20051031|SUN-FRI' => 12.45,
'20051010-20051031|FRI-SUN' => 18.45,
'20051101-20060115|TUE-THU' => 11.24,
'20051101-20060115|THU-MON' => 12.11
);
#--------------- end data ------------------
foreach my $date (@dates) {
foreach my $range (keys %prices) {
$newprices{$date}=$prices{$range} if &InRange($date,$range);
}
}
print "\n\nResults, assuming no redundancy or overlap in data: \n",
(map { my $np=$newprices{$_}; ("\nDay $_ :", ($np ? "\$$np" :
'UNKNOWN' )) } @dates),
"\n\n";
Yup, thats gonna get a big read