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

It's annoying to use localtime. By default its output is kind of useless

perl -le 'print join(",", @{[localtime]}[5,4,3,2,1,0])' 106,6,18,15,22,52

You have to add some extra statements to put it into more readable form:

perl -le '@_=localtime; print sprintf("%4d-%02d-%02d %02d:%02d:%02d", $_[5]+1900, $_[4]+1, @_[3,2,1,0])' 2006-07-18 15:57:36

But I'm wondering if there's a more compact way to do it (can be obfuscated), in one statement. Without cheating. For example:

perl -le'print join(",", (@_=@{[localtime]}[5,4,3,2,1,0]) && ($_[0]+1900, $_[1]+1, @_[2..5]))'

is obviously cheating, since the assignment and && basically make it into two statements (technically, no - but do you see the "spirit" of what I'm saying?). Can you do like a map on items in a list? I have something like this (non-working) in mind:

@t = (+ 1900, + 1, , , , ) = @{[localtime]}[reverse 0..5];

I'm guessing not but thought I'd ask.

(tiny update: I had the order reversed in the last example)

Replies are listed 'Best First'.
Re: golfing on localtime
by davorg (Chancellor) on Jul 18, 2006 at 14:03 UTC
    perl -le 'print scalar localtime'

    Or if you're pickier about the format:

    perl -MPOSIX=strftime -le 'print strftime "%Y-%m-%d %H:%M:%S", localti +me'

    Oh, and in your original code, print sprintf can be abbreviated to printf.

    --
    <http://dave.org.uk>

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

Re: golfing on localtime
by liverpole (Monsignor) on Jul 18, 2006 at 15:24 UTC
    Hi ForgotPasswordAgain,

    Is this the kind of thing you're looking for ...?

    + # Golfed generation of current date/time @t=map{$_+{4,1,5,1900}->{5-$i++}}(reverse localtime)[3..8]; + # Print the date/time printf "%d-%d-%d %02d:%02d:%02d\n", @t;

    Update:  Or even shorter (55 chars):

    @t=map$_+{1,1,0,1900}->{$i++},(localtime)[5,4,3,2,1,0];

    (Update:  Fixed typos in the above line).


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      Ha, yes that's brilliant.
Re: golfing on localtime
by Corion (Patriarch) on Jul 18, 2006 at 14:03 UTC

    I use the strftime function from the POSIX package for that - its only task is to give the output of localtime (and its siblings) a readable format:

    perl -MPOSIX=strftime -e "print strftime '%Y-%m-%d %H:%M:%S',localtime +;" 2006-07-18 16:02:08
Re: golfing on localtime
by shmem (Chancellor) on Jul 18, 2006 at 15:22 UTC
    Does this one pass as one statement for you?
    perl -le 'print "@{[map{(localtime)[$c++]+$_}(0,0,0,0,1,1900,0,0,0)]}" +'
    You've got to get rid of $c afterwards, though. And yes, it calls localtime 9 times. But this was about golf, wasn't it?

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: golfing on localtime
by explorer (Chaplain) on Jul 18, 2006 at 14:23 UTC
    I follow the standards of my old parents...
    perl -MDateTime -le 'print DateTime->now' 2006-07-18T14:21:40
    Yes, I kown, is NOT localtime, but... is golfing!... and is the method recommended.
Re: golfing on localtime
by ForgotPasswordAgain (Vicar) on Jul 18, 2006 at 14:25 UTC

    Sorry, in trying to "motivate" the problem, I've managed to explain the question badly.

    I know about strftime, it's right in the perldoc for localtime. What I was more interested in was the question at the end. I was just curious if there was some goatse-operator-esque way of tweaking a list without going through an intermediary variable. I know, it's a stupid question.

      As long as you only have adjustments of numbers, I'd go for List::MoreUtils' zip function:

      my @adjustments = ( +1900, +1, 0, 0, 0, 0, ); my @t = pairwise { $a+$b } @adjustments, @{[localtime]};

      If the operation differs between the elements of the target list/array, I guess a multi-map / MapCar is what you'll need:

      my @adjustments = ( sub { $_[0] + 1900 }, sub { $_[0] + 1 }, sub { $_[0] + 0 }, ... ); my @t = pairwise { $a->($b) } @adjustments, @{[localtime]};