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

I have a a progam which returns the date for the last monday or today if today is a monday. I have a sub routine version for the production code which does the job perfectly. Howvever in a moment if trying to challange myself I decided to see if I could do a online version.

The challange is to get 20061002 in one line so far i have a string " 106 9 2" from
printf "%4d%2d%2d",((localtime(time - ((1 - (localtime(time))[6]) +* -86400)))[5,4,3]); }

Can anyone help me finish it or is this the wrong aproach?

Replies are listed 'Best First'.
Re: The date last monday
by davorg (Chancellor) on Oct 03, 2006 at 10:52 UTC
    $ perl -MPOSIX=strftime -le 'print strftime "%Y%m%d", localtime(time - + ((1 - (localtime)[6]) * -86400))' 20061002
    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: The date last monday
by davidrw (Prior) on Oct 03, 2006 at 12:27 UTC
    A Date::Calc solution:
    perl -MDate::Calc=Today,Week_of_Year,Monday_of_Week -e 'printf "%04d%0 +2d%02d", Monday_of_Week(Week_of_Year(Today))'
Re: The date last monday
by johngg (Canon) on Oct 03, 2006 at 10:46 UTC
    Years are counted from 1900 and months are zero-based, ie January is 0 and December is 11.

    Cheers,

    JohnGG

    Update: Just noticed that you need leading zeros so use %02d to get those.

      I know and in production i have a sub routine to format as 20061002 but my challange is to do the formating and calulation in one line. Heres my sub
      sub get_CCYYMMDD{ my $timecode = $_[0]; my ($day, $month, $year) = (localtime($timecode))[3..5]; $year += 1900; $month++; $month = $month<10 ? "0".$month : $month; $day = $day<10 ? "0".$day : $day; my $today = $year.$month.$day; #print $today."\n"; return $today; }

      Am I asking to much to do this all in one go?

        You seem to have written a rather less flexible version of POSIX::strftime :-)

        use POSIX 'strftime'; sub get_CCYYMMDD { return strftime '%Y%m%d', $_[0]; }
        --
        <http://dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

        "Am I asking to much to do this all in one go?"

        Well. no, as previous posters have demonstrated. On the other hand, if I were to encounter a one-liner 'solution' in a code-review I'd flag it as a 'Maintenance problem'. The one-liner is cute and quirky and flashy. But the purpose of code is to be readable at 0300 by a half-asleep bloke who just got to the pager before it woke the Baby. I vote for simple and verbose every time.

        ----
        I Go Back to Sleep, Now.

        OGB

        Sorry I missed the drift of your OP. No, you are not asking too much at all. You need to transform the array slice using a map, like this

        perl -e 'printf qq{%4d%02d%02d\n},map{$_->[0]+1900,$_->[1]+1,$_->[2]}[ +((localtime(time-((1-(localtime(time))[6])* -86400)))[5,4,3])];'

        Note that the slice is passed into the map as an anonymus list.

        Cheers,

        JohnGG