InfiniteLoop has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks
 
I need to write a function to return, for a given date range (Time::Piece objects), a list of week days. For eg: given
  Oct 01, 2005 - Oct 14, 2005 would return:
{ Sundays => [Oct 2,2005 Oct 9,2005], Monday => [Oct 3,2005 Oct 10,2005], Tuesday => .... }
The representation is bit coarse, but you know what I mean.
I have looked up the venerable CPAN and searched the perlmonks, but could not find an answer. Can any one throw some light on this matter ?

Update:
Ok, one solution I could think of is, I loop thru the start date and end date, in increments of 7 days, and in the loop, push appropriate values into 7 arrays (one for each week).

Replies are listed 'Best First'.
Re: week days in a given date range
by BigLug (Chaplain) on Oct 20, 2005 at 22:51 UTC
    Because it's "what I do" ... here's the DateTime solution. I know you're already working in Time::Piece, so you probably want to go with the matching solution above.

    use DateTime; my $start_date = new DateTime( year => 2005, month => 10, day => 1 ); my $end_date = new DateTime( year => 2005, month => 10, day => 14 ); while( $start_date <= $end_date ) { push( @{$result{ $start_date->day_name }}, $start_date->clone ); $start_date->add( days => 1 ); }
Re: week days in a given date range
by shemp (Deacon) on Oct 20, 2005 at 22:07 UTC
    Use the Date::Calc CPAN module. The function Day_of_Week() gives a numeric value for the day of the week, i.e. monday is 1, etc. Use that on the mimimum date in your range. Also use the Add_Delta_Days() function to keep adding one day to the initial day until you get to the end of the date range. Keep track of the dates that are each weekday. You'll have to do some playing around to get everything in the format you desire. Perhaps i'll post a code solution when i get home from work.

    I use the most powerful debugger available: print!
Re: week days in a given date range
by InfiniteSilence (Curate) on Oct 20, 2005 at 22:19 UTC
    Wow, Time::Piece is kind of cool.

    At any rate, you want to do something like this:

    C:\Temp>perl -MTime::Piece -e "$t = localtime; for(1..7){$anoDate = lo +caltime($t->epoch +($_*60*60*24)); print $anoDate->wdayname};" FriSatSunMonTueWedThu
    You can make a hash that uses the day names as keys and stores the actual dates as arrays to group them the way you want. Instead of 1..x you want to know how many days there are between your start date and end date.

    Update:Changed the - to a + in the code to count forward rather than backward.

    Celebrate Intellectual Diversity

Re: week days in a given date range
by ambrus (Abbot) on Oct 21, 2005 at 09:01 UTC

    Since I'm in such a good mood, I give you a solution using Date::Manip, the coolest date module.

    perl -we 'use Date::Manip; use Data::Dumper; my ($date, $end) = @ARGV; + my %out; while (Date_Cmp($date, $end) <= 0) { push @{$out{UnixDate($ +date, "%A")}}, UnixDate($date, "%b %e, %Y"); $date = DateCalc($date, +"+1 day"); } print Dumper \%out;' 'Oct 01, 2005' 'Oct 16, 2005'
    Output:
Re: week days in a given date range
by blazar (Canon) on Oct 21, 2005 at 10:27 UTC

    I don't know Time::Piece; I've been using Date::Calc (functional UI) and DateTime (OO UI) for date/time calculations: the former has a bunch of Day_of_Week* functions, I'm not really sure about the latter, but I'm confident it has some suitable method too.

    In particular:

    #!/usr/bin/perl -l use strict; use warnings; use Date::Calc qw/:all/; print(Day_of_Week_to_Text(Day_of_Week(Today))); __END__

    Now referring to Date::Calc (with which I'm more familiar than with DateTime), you could get each date in the range of your Time::Piece object and cast it into a form that could be passed to a suitable function of the former module, e.g. a string in ISO format.

    HTH