There has been some debate at our local perl mongers group about when to meet this month, given that we meet on the second Tuesday of the month.

From: Oliver Paukstadt <***> Reply-To: Stuttgart Perl Mongers <stuttgart-pm@pm.org> To: Stuttgart Perl Mongers <stuttgart-pm@pm.org> Subject: Re: [Stuttgart-PM] Treffen DIESE Woche On Mon, 2009-04-06 at 18:59 +0200, Rolf Schaufelberger wrote: > > > > Um das mal dauerhaft und stilgerecht zu lösen : > > > > perl -MDateTime -e ' for (1..20 ) { my $d=DateTime- > > >new(year=>2009,month=>4,day=>$_); if ( $d->weekday_of_month ==2 +&& > > $d->day_of_week ==2 ) { print "$_\n"; last; }}' > > 14 > > Couldn't resist: perl -MDate::Calc=:all -le 'print Date_to_Text(Nth_Weekday_of_Month_Year(2009,4,2,2))' Gruss Oliver

Modules? Not for golf. I came up with this:

perl -le'{@l=localtime($t-=((localtime$t)[3]-1)*86400);$t+=(($l[6]<3?7 +:14)-$l[6]+2)*86400;$t<time?($t+=2592000,redo):print$..localtime$t}'

128 chars not counting perl -le and not counting the surrounding single quotes. I am sure you can do better ;-)

Rules: no modules; if the second Tuesday of the current month has passed, give the second Tuesday of the next month. No requirements on the output format except it must show the correct year, month and day (in any unambiguous order).

update: using gmtime instead of localtime gives 119 chars:

perl -le '{@l=gmtime($t-=((gmtime$t)[3]-1)*86400);$t+=(($l[6]<3?7:14)- +$l[6]+2)*86400;$t<time?($t+=2592000,redo):print$..gmtime$t}'

update 2: joint result of #perlgolf (mtve,shmem), 92 chars:

perl -le 'sub f{gmtime$_*86400}$_+=30while($_+=9+7*(($x=(f$_-=(f)[3]-1 +)[6])>2)-$x)*86400<time;print~~f'

Replies are listed 'Best First'.
Re: (Golf) Next second Tuesday
by codeacrobat (Chaplain) on Apr 07, 2009 at 23:30 UTC
Re: (Golf) Next second Tuesday
by ambrus (Abbot) on Apr 08, 2009 at 09:21 UTC

    You do know that this works, right?

    perl -we 'use Date::Manip; print UnixDate("second tuesday of april", " +%c\n")'

      Now I know it - that's really nice, ambrus++. But its not golf ;-)

        Well, it's already not too much longer than the other solutions in your thread, but if you want golf, here's my try.

        perl -MDate::Manip -E'say UnixDate"2ndtueofapr","%c"'

        That strange words stands for 2nd (second) tue (Tuesday) of apr (April) but apparently Date::Manip follows the tradition of BASIC in not requiring spaces.

        Update 2011-02-07: this no longer works in Date::Manip version 6.12. This works:

        perl -MDate::Manip -E'say UnixDate"2nd tue of apr","%c"'
Re: (Golf) Next second Tuesday
by linuxer (Curate) on Apr 08, 2009 at 00:22 UTC

    I parsed the output of the cal command for my solution:

    cal 3 2009 | perl -anle '$.==1&&do{print};@F=unpack"A3"x7,$_;$.>2&&$F[ +2]=~m/^\s*\d+$/&&++$a==2&&print$F[2];'

    If you want to specify the day's shortname (like 'Tu' for Tuesday) I had the slightly longer version:

    cal 4 2009 | perl -anle '$.==1&&do{print};@F=unpack"A3"x7,$_;$.==2&&do +{@i{@F}=0..$#F};$.>2&&$F[$i{"Tu"}]=~m/^\s*\d+$/&&++$a==2&&print$F[$i{ +"Tu"}];'

    First one counts 82 and the second 121 characters (not counted cal [arguments] | perl -anle and the surrounding single quotes.

      well, for that matter, 69 chars not counting 'date '...

      date "+%Y-%m-$(env LC_ALL=C cal|sed 1,2d|cut -c7-8|grep '[0-9]'|sed -n + 2p)"

      ...but the rules say

      if the second Tuesday of the current month has passed, give the second Tuesday of the next month

      so that doesn't qualify either ;-)

Re: (Golf) Next second Tuesday
by mr_mischief (Monsignor) on Apr 15, 2009 at 19:05 UTC

    Nothing but Perl here...

    85:

    perl -E '$d=86400;$t=$^T-$d;($m,$w)=(gmtime($t+=$d))[3,6]until$m>7&&$m<15&&$w==2;say-gmtime$t'

    82 if today being the second Tuesday of the month means you've missed scheduling the meeting already:

    perl -E '$d=86400;$t=$^T;($m,$w)=(gmtime($t+=$d))[3,6]until$m>7&&$m<15&&$w==2;say-gmtime$t'

    Update (2009-04-16, 18:35 GMT):
    Trimmed one character for the version that works even if the current day is the second Tuesday of the month, for 84:

    perl -E '$t=$^T-($d=86400);($m,$w)=(gmtime($t+=$d))[3,6]until$m>7&&$m<15&&$w==2;say-gmtime$t'

    end of update