Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Week Partitioner

by japhy (Canon)
on Mar 09, 2001 at 02:02 UTC ( #63110=sourcecode: print w/ replies, xml ) Need Help??

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;

Comment on Week Partitioner
Select or Download Code

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://63110]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (6)
As of 2014-07-30 00:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (229 votes), past polls