Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Gettting the last Friday of every month using Time::Piece

by Anonymous Monk
on Jun 30, 2014 at 15:43 UTC ( #1091742=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks!

I need to get all last fridays of every month using Time::Piece, I am stuck here:
#!/usr/bin/perl use strict; use warnings; use Time::Piece; my $t = Time::Piece->new(); my $day_of_month = $t->day_of_month; print "\nTodays Number: $day_of_month\n\n"; my $year = $ARGV[ 0 ] || 2014; foreach my $month ( 1..12 ) { my $tdates = $t->strptime("$year/$month/$day_of_month", "%Y/%m/%d") +; my $day_of_week = $tdates->day_of_week; my $wday_name = $tdates->wdayname; print "Month: $month | Week Day Name:$wday_name | Week Day Number:$ +day_of_week\n"; #Need to get the last Friday of every month here: }

Any suggestions? Thanks for looking!

Replies are listed 'Best First'.
Re: Gettting the last Friday of every month using Time::Piece
by toolic (Bishop) on Jun 30, 2014 at 16:08 UTC
    use strict; use warnings; use Time::Piece; use Time::Seconds; my $t = Time::Piece->new(); my $year = $ARGV[ 0 ] || 2014; foreach my $month ( 1 .. 12 ) { my $tdates = $t->strptime("$year/$month/1", '%Y/%m/%d'); my $day_of_month = $tdates->month_last_day(); $tdates = $t->strptime("$year/$month/$day_of_month", '%Y/%m/%d'); while ($tdates->wdayname ne 'Fri') { $tdates -= ONE_DAY; } printf "Last Friday of Month %02d is %s\n", $month, $tdates->ymd() +; } __END__ Last Friday of Month 01 is 2014-01-31 Last Friday of Month 02 is 2014-02-28 Last Friday of Month 03 is 2014-03-28 Last Friday of Month 04 is 2014-04-25 Last Friday of Month 05 is 2014-05-30 Last Friday of Month 06 is 2014-06-27 Last Friday of Month 07 is 2014-07-25 Last Friday of Month 08 is 2014-08-29 Last Friday of Month 09 is 2014-09-26 Last Friday of Month 10 is 2014-10-31 Last Friday of Month 11 is 2014-11-28 Last Friday of Month 12 is 2014-12-26
Re: Gettting the last Friday of every month using Time::Piece
by poj (Abbot) on Jun 30, 2014 at 16:49 UTC
    #!perl use strict; use Time::Piece ; my $year = 2014; foreach my $month ( 1..12 ) { my $t = Time::Piece->strptime("$year/$month/01", "%Y/%m/%d"); my $dd = 34 - $t->_wday; # sun=0 $dd -= 7 if $dd > $t->month_last_day; print "$year $month $dd\n"; }
    poj
      Whats with the 34?
      my $dd = 34 - $t->_wday; # sun=0
        35= 5*7 days after the 1st (the "36th") you'll have the same weekday again

        36- _wday gives a Sunday

        2 days before Sunday is Friday => 34- _wday

        ... and so on

        Cheers Rolf

        (addicted to the Perl Programming Language)

Re: Gettting the last Friday of every month using Time::Piece
by LanX (Cardinal) on Jun 30, 2014 at 15:57 UTC
    > Any suggestions? 

    Take $n=$lastday->day_of_week of the last day of the month (according to Time::Piece 0=Sunday)

    Then subtract $diff days from $lastday to get day_of_week 5 = Friday.

    Ie. $diff = ($n-5) % 7

    Cheers Rolf

    (addicted to the Perl Programming Language)

Re: Gettting the last Friday of every month using Time::Piece
by Jim (Curate) on Jun 30, 2014 at 18:17 UTC

    From the Introduction to the Wikipedia article titled Determination of the day of the week:

    The basic approach of nearly all of the methods to calculate the day of the week begins by starting from an ‘anchor date’: a known pair (such as January 1, 1800 as a Wednesday), determining the number of days between the known day and the day that you are trying to determine, and using arithmetic modulo 7 to find a new numerical day of the week.
Re: Gettting the last Friday of every month using Time::Piece
by gurpreetsingh13 (Scribe) on Jul 01, 2014 at 10:02 UTC

    Please check if this works for you. Simple solution to work for each month in reverse direction.

    use v5.14; #!/usr/bin/perl use strict; use warnings; use Time::Piece; my $t = Time::Piece->new(); my $year = $ARGV[0] || 2014; foreach my $month ( 1 .. 12 ) { #Make an object with first day of each month and use it to get las +t day of each month my $tFirstDayObject = $t->strptime( "$year/$month/1", "%Y/%m/%d" ) +; my $monthLastDay = $tFirstDayObject->month_last_day; #Now make an object with this last date and use it to get last wee +kDay number my $tLastDayObject = $t->strptime( "$year/$month/$monthLastDay", " +%Y/%m/%d" ); my $weekDay = $tLastDayObject->wday; #Now calculate how many days to add in this weekDay taking Sunday +as the first day my $daysToMoveBack = 0; $weekDay >= 6 ? ( $daysToMoveBack = $weekDay - 6 ) : ( $daysToMove +Back = $weekDay + 1 ); my $lastFridayDate = $monthLastDay - $daysToMoveBack; #Now make an object with this $lastFridayDate for each month my $tLastFridayObject = $t->strptime( "$year/$month/$lastFridayDat +e", "%Y/%m/%d" ); say $tLastFridayObject->cdate; }
    Output:
    Fri Jan 31 00:00:00 2014
    Fri Feb 28 00:00:00 2014
    Fri Mar 28 00:00:00 2014
    Fri Apr 25 00:00:00 2014
    Fri May 30 00:00:00 2014
    Fri Jun 27 00:00:00 2014
    Fri Jul 25 00:00:00 2014
    Fri Aug 29 00:00:00 2014
    Fri Sep 26 00:00:00 2014
    Fri Oct 31 00:00:00 2014
    Fri Nov 28 00:00:00 2014
    Fri Dec 26 00:00:00 2014

      ++gurpreetsingh13. By your use of meaningful variable names and explanatory comments, your script explains what it does and how it does it. One is able to understand your algorithm by reading just the script itself, without having to refer to any module documentation.

      This…

      my $daysToMoveBack = 0; $weekDay >= 6 ? ( $daysToMoveBack = $weekDay - 6 ) : ( $daysToMove +Back = $weekDay + 1 );

      …is more succinctly written like this…

      my $daysToMoveBack = $weekDay >= 6 ? $weekDay - 6 : $weekDay + 1;
        Great thanks for the correction and improvement.

      Here's my refactored version of your demonstration script:

      use strict; use warnings; use Time::Piece; my $year = shift @ARGV || 2014; my $p = '%Y/%m/%d'; # strptime() format my $f = '%a %b %d %Y'; # strftime() format my $t = Time::Piece->new(); for my $month (1 .. 12) { # Compute the last day of the month... my $monthLastDay = $t->strptime("$year/$month/1", $p)->month_last_day(); # Compute the day of the week of the last day of the month (Sunday + = 1)... my $weekDay = $t->strptime("$year/$month/$monthLastDay", $p)->wday(); # Compute the day of the last Friday of the month (Friday = 6)... my $lastFridayDate = $monthLastDay - (($weekDay - 6) % 7); # Compute the last Friday of the month... my $lastFriday = $t->strptime("$year/$month/$lastFridayDate", $p)->strftime($ +f); print "$lastFriday\n"; } exit 0; __END__ Fri Jan 31 2014 Fri Feb 28 2014 Fri Mar 28 2014 Fri Apr 25 2014 Fri May 30 2014 Fri Jun 27 2014 Fri Jul 25 2014 Fri Aug 29 2014 Fri Sep 26 2014 Fri Oct 31 2014 Fri Nov 28 2014 Fri Dec 26 2014

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1091742]
Approved by toolic
Front-paged by Jim
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (9)
As of 2021-03-05 22:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favorite kind of desktop background is:











    Results (115 votes). Check out past polls.

    Notices?