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

Calculating the "nearest" week

by hacker (Priest)
on Apr 25, 2005 at 01:31 UTC ( [id://451069]=perlquestion: print w/replies, xml ) Need Help??

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

A confusing node title, but please read on...

I'm trying to come up with a simple little script that can spit out a week's worth of days (5 work days), regardless of what day I execute the script on.

For example, if I run the script on Saturday (i.e. the 6th day of the week), I want it to output the previous Monday through Friday.

If I execute the script on Wednesday, it should output the Monday of that week, Tuesday, Wednesday (the day I run it), tomorrow (Thursday) and the day after (Friday).

This is more of a math question than Perl I suppose. Is there an easy way to find the closest week to the day I execute the script? It will either be the previous week, or the current week, depending on which day I run the script. Something in Date::Calc? Some other module?

Thanks.

Replies are listed 'Best First'.
Re: Calculating the "nearest" week
by eibwen (Friar) on Apr 25, 2005 at 01:48 UTC
    I've found Date::Manip to be particularly useful for complex date functions.

    if ((localtime(time))[6] == 0) { # Sunday print Date::Manip::ParseDate('next Monday'); print Date::Manip::DateCalc('next Monday','+ 4 business days'); } elsif ((localtime(time))[6] == 1) { # Monday print Date::Manip::ParseDate('today'); print Date::Manip::DateCalc('today','+ 4 business days'); } else { print Date::Manip::ParseDate('last Monday'); print Date::Manip::DateCalc('last Monday','+ 4 business days'); }

    UPDATE: Added consideration for running the code on Monday. I don't think there are any potential implications of a MTWTFSS vs a SMTWTFS week (Saturday is still closer to "last" week; Sunday is still closer to "next" week).

Re: Calculating the "nearest" week
by bobf (Monsignor) on Apr 25, 2005 at 04:21 UTC

    Here is a solution using Date::Calc, which could be shortened up a bit. I hard coded a range of dates to serve as an example:

    use warnings; use strict; use Date::Calc qw( Week_of_Year Monday_of_Week Month_to_Text ); # Date::Calc uses 1 = Monday, ... 7 = Sunday foreach my $date ( 1 .. 20 ) { my $week = Week_of_Year( 2005, 4, $date ); # see docs for caveats my ( $year, $month, $day ) = Monday_of_Week( $week, 2005 ); print "The Monday before April $date was ", Month_to_Text( $month ), " $day\n"; }

    Output:

    The Monday before April 1 was March 28 The Monday before April 2 was March 28 The Monday before April 3 was March 28 The Monday before April 4 was April 4 The Monday before April 5 was April 4 The Monday before April 6 was April 4 The Monday before April 7 was April 4 The Monday before April 8 was April 4 The Monday before April 9 was April 4 The Monday before April 10 was April 4 The Monday before April 11 was April 11 The Monday before April 12 was April 11 The Monday before April 13 was April 11 The Monday before April 14 was April 11 The Monday before April 15 was April 11 The Monday before April 16 was April 11 The Monday before April 17 was April 11 The Monday before April 18 was April 18 The Monday before April 19 was April 18 The Monday before April 20 was April 18

    Once you know the starting date, it is trivial to calculate the rest. :)

    HTH

Re: Calculating the "nearest" week
by tlm (Prior) on Apr 25, 2005 at 01:56 UTC

    Try this:

    use strict; use warnings; use Time::Local; my $sec_per_day = 60*60*24; my $now = time; my @now = localtime( $now ); my $today_noon = timelocal( 0, 0, 12, @now[ 3..5 ] ); my $delta = ( $now[ 6 ] - 1 ) % 7; my $monday_noon = $today_noon - $delta*$sec_per_day; my $t = $monday_noon; for ( 1 .. 5 ) { my @t = localtime $t; print +( scalar localtime timelocal( 0, 0, 0, @t[ 3..5 ] ) ), $/; $t += $sec_per_day; } __END__ Mon Apr 18 12:00:00 2005 Tue Apr 19 12:00:00 2005 Wed Apr 20 12:00:00 2005 Thu Apr 21 12:00:00 2005 Fri Apr 22 12:00:00 2005

    Update: Fixed the algorithm, after getting clarification on the specs from hacker via CB.

    the lowliest monk

Re: Calculating the "nearest" week
by TedPride (Priest) on Apr 25, 2005 at 07:18 UTC
    It's really very simple.
    use strict; use warnings; my @d = qw/Sunday Monday Tuesday Wednesday Thursday Friday Saturday/; my @m = qw/January February March April May June July August September + October November December/; my $t = time(); $t += (1-(localtime($t))[6])*86400; for (1..5) { @_ = localtime($t); $t += 86400; print "$d[$_] ".$m[$_[4]+1]." $_[3] ".($_[5]+1900)."\n"; }
Re: Calculating the "nearest" week
by adrianh (Chancellor) on Apr 25, 2005 at 17:02 UTC
    use DateTime; use DateTime::Duration; my $start_of_week = DateTime->now->truncate( to => 'week' ); my $one_day = DateTime::Duration->new( days => 1 ); print +($start_of_week + $one_day * $_)->strftime( "%F\n" ) for ( 0..4 + );

    I love DateTime :-)

Re: Calculating the "nearest" week
by NateTut (Deacon) on Apr 25, 2005 at 15:01 UTC
    You don't really say if you are looking for the whole date, including year or not. But if you are including the year don't forget to figure out what to do around the new year. Its easy to assume that you're always working in the same year, when you may not be.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://451069]
Approved by moot
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-04-19 09:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found