in reply to Is there an easy way to get the start date of the current week?

One way:

#! perl -slw use strict; sub lastSunday { my $now = time; $now -= 43200 while scalar localtime($now) !~ m[Sun]; return $now; } print scalar localtime( lastSunday() );
  • Comment on Re: Is there an easy way to get the start date of the current week?
  • Download Code

Replies are listed 'Best First'.
Re^2: Is there an easy way to get the start date of the current week?
by TomDLux (Vicar) on Aug 22, 2010 at 02:14 UTC

    I just wrote another message in which I mention rarely using the components from list-context localtime(), except to feed into strftime(). This is one of those rare situations which call for using the components. In scalar context, localtime() gives you a fully formatted date-time string, but in list context it returns:

    my ( $seconds, $minutes, $hours, $day_of_month, $month_idx, $years_since_1900, $day_of_week_number, $day_of_year, $id_dst ) = localtime($now);
    So rather than generating a date string "Sat Aug 21 22:00:53 2010" and then parsing it with a regex ( not even substr()! .. shocking! ), why not use the day of the week component .... 0 == Sunday through to 6 == Saturday.
    $now -= 43200 while (localtime($now))[6]; # count back half days till +Sunday

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

      So rather than generating a date string "Sat Aug 21 22:00:53 2010" and then parsing it with a regex ( not even substr()! .. shocking! ), why not use the day of the week component

      How many times do you need to calculate 'last sunday' in any given run of a program?

      I think that if you are doing it more than once, you've programmed an error. Even if the run transitions midnight, using two different definitions of that term within a single run of the program, is likely to be an inconsistency with ramifications.

      On that basis, you should only calculate it once. And so the performance gain of only taking 3 milliseconds over 6 is neither here nor there.

      Even if you do the sensible thing and (having obtained the day of week) perform a calculation rather than a loop:

      sub lastSunday2 { my $now = time; my @now = localtime $now; return $now -= ( $now[ 6 ] * 2 - 1 ) * 43200; }

      And so cut the cost of that single call to 1 millisecond, you're still never going to notice it.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re^2: Is there an easy way to get the start date of the current week?
by Tux (Canon) on Aug 22, 2010 at 06:43 UTC

    This can break in two ways:

    1. In a locale where "Sun" is not Sunday
    2. If Monday is the first day of the week, in which case you will have to go forward (for the question asked). You've chosen your sub name to be clear that you're going backward though.

    Enjoy, Have FUN! H.Merijn
      The scalar value of localtime is explicitly not locale dependent. It is a fixed format, see ctime(3)
        perlfunc also mentions this
        This scalar value is not locale dependent but is a Perl builtin. ... To get somewhat similar but locale dependent date strings, set up your locale environment variables appropriately ... use POSIX qw(strftime);

        I stand corrected.

        I however probably still wouldn't rely on it as there are probably way too many other functions that /do/ depend on the locale, or suddenly behave different if POSIX comes into play (or when it explicitely does not), or when modules happen to be in place that overrule this default.


        Enjoy, Have FUN! H.Merijn
      In a locale where "Sun" is not Sunday

      But then the routine would not be called lastSunday() either...

        Not to be arguing, but what /would/ it be called then, when using the script in a multi-langual environment, or when you do not know what the locale will be at execution time?

        I really like the simplicity of the approach. I always want to answer the stupid question "How do I print yesterday in perl?" with 'print "yesterday"', which is a perfect answer, but obviously not what the question was about. I've hit this locale problem way too often to not care, and if you'd use a regex match, the easy way out is to use { local $ENV{LC_TIME} = "en_US"; ... }.


        Enjoy, Have FUN! H.Merijn