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

Hi Monks,

I have one problem by capturing the Date. I want to capture the date like this:

August, 24-28, 2009

(i.e.) If i am running the perl today means i want to capture this week date from monday to friday.
For this any module is there. Please help me.
Regards,
Balaji S

Replies are listed 'Best First'.
Re: About this week Date
by ambrus (Abbot) on Aug 27, 2009 at 14:08 UTC

    This task has two parts: one is to find the first and last day of the current week, the other is to print the interval as a human-readable format. For the first, we'll use the Date::Manip::Date_GetPrev function which does the right thing. I have to hand-roll the second one.

    Here's my solution. This assumes your dates start with Monday.

    #!perl + use warnings; use strict; + use Date::Manip; my $mon = Date_GetPrev("now", "monday", 1, 8); my $fri = DateCalc($mon, "+4days"); my($mony, $monm) = UnixDate($mon, "%y", "%m"); my($friy, $frim) = UnixDate($fri, "%y", "%m"); my $r; if ($monm == $frim) { $r = UnixDate($mon, "%B %e-") . UnixDate($fri, "%e, %Y\n") } elsif ($mony == $friy) { $r = UnixDate($mon, "%B %e-") . UnixDate($fri, "%B %e, %Y\n") } else { $r = die "homework for the reader"; } print $r; __END__
Re: About this week Date
by bv (Friar) on Aug 27, 2009 at 14:04 UTC

    The builtin function localtime gives you all the elements you need.

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); my $monday = $mday - $wday + 1; my $friday = $mday - $wday + 5;

    Of course this doesn't work if you aren't in the middle of a month (e.g. if ($mday - $wday + 1) < 0). You could take your time() and add or subtract 24*60*60 seconds per day to get the right unix time, then convert to date with localtime()

    $,=' ';$\=',';$_=[qw,Just another Perl hacker,];print@$_;
Re: About this week Date
by Sewi (Friar) on Aug 27, 2009 at 14:44 UTC
    What should happen if you run the script on Sat or Sun?

    my @Now = localtime(time); print "Today: $Now[3] - $Now[6]\n"; my $Mon = time - (86400 * ($Now[6] - 1)); my @Monday = localtime($Mon); print "Monday: $Monday[3] - $Monday[6]\n"; my $Fri = $Mon + (86400 * 4); my @Friday = localtime($Fri); print "Friday: $Friday[3] - $Friday[6]\n";
    Explanation:
  • Get the splitted time values for now - returns the day of week as 6 starting with 0 for sunday
  • Monday is today - (seconds_per_day * (day_of_week - ))
  • Friday is 5 days after monday
  • This won't work in the following cases:

  • On the two change days for daylight saving there is a one hour for each day where the next day is not 86400 seconds away.
  • There has been a time (and there will be a time) where some days were skipped to match the calendar to the earth/sun relation.
  • You could advoid this by using localtime to get the current days values and step back (and forward) day-by-day by using timelocal(0,0,0,day,month,year) - 1 or timelocal(59,59,23,day,month,year) + 1 until you reach a monday or friday, but usually the above sample is accurate enough.
Re: About this week Date
by Malus (Acolyte) on Aug 27, 2009 at 15:49 UTC
    #!/usr/bin/perl use strict; use warnings; sub this_monday_thru_friday { my ($now,$wday,$mon_secs,$fri_secs,@mth,@mon,@fri); $now = time(); $wday = (localtime($now))[6]; $mon_secs = ( 1 - $wday ) * 60 * 60 * 24 + $now; $fri_secs = ( 5 - $wday ) * 60 * 60 * 24 + $now; @mth = qw( January February March April May June July August September October November December ); @mon = (localtime($mon_secs))[3..5]; # mday,month,year @fri = (localtime($fri_secs))[3..5]; # mday,month,year $mon[2] += 1900; # change monday year to four digits $fri[2] += 1900; # ... do the same for this friday return $mth[$mon[1]],@mon[0,2],$mth[$fri[1]],@fri[0,2]; } # Example output: August 24 2009 August 28 2009 printf "%s\n", join " ", this_monday_thru_friday();