Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jbodoni (3320)

Journal of jbodoni (3320)

Monday September 30, 2002
01:48 PM

Some actual Perl content: finding the previous week

[ #8104 ]
I needed to find the start and end dates for the previous calendar week, and couldn't find anything pre-rolled, so here's what I came up with, which populates $startdate and $enddate. It'll be posted on perlmonks, but I wanted to show it here too. Does anyone have anything better, or any suggestions on how I can improve this?

Please be gentle, this is the first of my code I've posted for public consumption. 8)

    #    0    1    2     3     4    5     6     7     8
    # ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
    my $wday = (localtime(time()))[6] + 1;
    # how many days into the current week are we?

    my $endseconds   = time()      - ($wday * 24 * 60 * 60);
    # subtract that many days from today.  this tells us when Saturday (of the previous calendar week) was

    my $startseconds = $endseconds - (6     * 24 * 60 * 60);
    # six days before that was the Sunday we're interested in

    my $year  = (localtime($startseconds))[5] + 1900;
    my $month = (localtime($startseconds))[4] + 1;
    my $day   = (localtime($startseconds))[3];
    if (length($month) < 2) {$month = "0$month"}
    if (length($day)   < 2) {$day   = "0$day"}
    $startdate = "$year$month$day";

    $year  = (localtime($endseconds))[5] + 1900;
    $month = (localtime($endseconds))[4] + 1;
    $day   = (localtime($endseconds))[3];
    if (length($month) < 2) {$month = "0$month"}
    if (length($day)   < 2) {$day   = "0$day"}
    $enddate = "$year$month$day";

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • I suggest looking into the Time::Piece module, to get rid of all those nondescriptive subscripts.

    J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
    • Something like this? :)
      use Time::Piece;
      use Time::Seconds;

      my $time  = localtime();
      my $end   = $time - ONE_DAY * $time->wday;
      my $start = $end - ONE_DAY * 6;

      my ($startdate, $enddate) = map $_->strftime('%Y%m%d'), $start, $end;

      print "Start: $startdate, End: $enddate\n";
  • It's weird how many newbies fall back to this kind of code:

      if (length($month) < 2) {$month = "0$month"}

    Horrors. My advice: use sprintf(). In fact, you can combine the sprintf for year, month and day into

     $enddate = sprintf "%04d%02d%02d", $y+1900, $m+1, $d;

    While we're at it: there's still more you can group, like this getting the year, month and day pout of a localtime() list value at once, ready for the above snippet:

      my($d, $m, $y) = (localtime($endseconds))[3, 4, 5]

    • Matt's Script Archive code did it that way, so a lot of junior perlhackerwannabe's also adopted that style.

      {sigh} Bad memes.

      • Randal L. Schwartz
      • Stonehenge
      • What does it say about me if I didn't adopt that style courtesy of Matt's Script Archive?

        What can I say? Being new to the language, I didn't remember sprintf when writing the code, opting instead for something easier, simpler, and possibly more legible. 8)

  • Thanks for your suggestions, I appreciate the feedback!

    Argh, this is frustrating. How is a novice Perlie to find out about this sort of thing? I search CPAN aggresively for "calendar week", "previous week", and something else I can't recall right now. I thumbed through Ye Olde Cookbook, the Llama, and The Camel. What else should I have done?

    How did you folks find out about Time::Piece initially?


    • I can't remember how I first found out about Time::Piece. I know that I had a design on my whiteboard for an identical module for the first six months of 2000, and then Matt Sergeant suddenly wrote it. No, he didn't have any contact with my whiteboard, but he did have an identical design from Larry Wall in the early part of that year.

      I suggest looking through new modules [] each day; it will give you a chance to become familiar with what's out there. You could go read the module list, but it would take fo

      J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers