http://www.perlmonks.org?node_id=63110
Category: Utility scripts
Author/Contact Info Jeff japhy Pinyan, japhy@pobox.com
Description: This program takes a month and a year, and returns output like cal, for the days of the month between Monday and Friday.
Here's the function library:
# monthutils.pl

my @dow = qw( Sun Mon Tue Wed Thu Fri Sat );
my @dom = (31,28,31,30,31,30,31,31,30,31,30,31);
my %feb;  # for caching feburary dates


sub getFirstNonWeekend {
  my ($month, $year) = @_;
  my $first = timelocal(0,0,12, 1, $month-1, $year-1900);
  my $shift = ((localtime $first)[6] + 1) % 7;

  if ($shift < 2) {
    $first += 86400 * (2 - $shift) if $shift < 2;
    return ($first, 3 - $shift, 1);
  }

  return ($first, 1, $shift - 1);
}


sub partitionWeekdays {
  my ($month, $year, $dom, $dow) = @_;
  my $last = lastDay($month,$year);
  my @weeks;

  # week is completed in the month
  while ($dom + 4 <= $last) {
    push @weeks, [ $dom .. ($dom + 5 - $dow) ];

    $dom += 8 - $dow;
    $dow = 1;
  }

  # month ends before week
  push @weeks, [ $dom .. $last ] if $dom <= $last;

  return @weeks;
}


sub lastDay {
  my ($m,$y) = @_;
  return $dom[$m-1] if $m != 2;
  return $feb{$y} if $feb{$y};
  return $feb{$y} = 29 if
    $y % 4 == 0 and
    ($y % 100 or $y % 400 == 0);
  return $feb{$y} = 28;
}


1;
And here's the program:
#!/usr/bin/perl -w

use Time::Local;
use strict;

require "monthutils.pl";  # above

my ($month, $year) = @ARGV or die << "USAGE";
usage: week-partition MONTH YEAR

  MONTH: ex. 3 (for March)
  YEAR:  ex. 2001

USAGE


print "Partition for $month/$year\n\n";
print " M  T  W  T  F\n";

my @weeks = partitionWeekdays(
  $month,
  $year,
  (getFirstNonWeekend($month, $year))[1,2]
);

unshift @{ $weeks[0] }, ("") x (5 - @{ $weeks[0] });
push @{ $weeks[-1] }, ("") x (5 - @{ $weeks[-1] });

printf "%2s %2s %2s %2s %2s\n", @$_ for @weeks;