in reply to Re^2: Date/Time Manipulation
in thread Date/Time Manipulation

Forgot to log in, RobertJ. Again thanks.

Replies are listed 'Best First'.
Re^4: Date/Time Manipulation
by johngg (Canon) on May 25, 2016 at 15:20 UTC

    Be aware that you might not be such a happy camper if the times fall within the hour after midnight! That code matches and captures, in the special variable $1, the two digits following a space, i.e. the hour value. It then executes (e modifier) the sprintf command in the substitution to replace the hour with a decremented value ($1 - 1). The q{ %2.2i} is the format specifier; q{ %02d} would also work. This method will break down if the hour is zero.

    The simple way.

    $ perl -Mstrict -Mwarnings -E ' my $dateStr = q{2016-05-16 00:51:07}; $dateStr =~ s{ (\d\d)}{ sprintf q{ %2.2i}, $1 - 1 }e; say $dateStr;' 2016-05-16 -01:51:07 $

    A little more robust.

    $ perl -MTime::Piece -MTime::Seconds -Mstrict -Mwarnings -E ' my $dateStr = q{2016-05-16 00:51:07}; my $dateFmt = q{%Y-%m-%d %H:%M:%S}; my $tp = Time::Piece->strptime( $dateStr, $dateFmt ); $tp -= ONE_HOUR; say $tp->strftime( $dateFmt );' 2016-05-15 23:51:07 $

    I hope this is of interest.

    Cheers,

    JohnGG

      The original spec was pretty clear, I think. Here's the relevant bit:

      All the times are during the daytime so I do not have to worry about "role-over" at midnight.

      HTH.

Re^4: Date/Time Manipulation
by RobertJ (Acolyte) on May 25, 2016 at 18:36 UTC

    OK I have been looking at that statement

    $stuff =~ s/ (\d\d)/sprintf(" %2.2i",$1-1)/e;

    I have poured over my Perl O'Reilly book and am still clueless. Since the input lines look like this

    2016-05-16 10:51:07 random text

    How does the expression pick out the hours versus any other two digits?

    Then what does the sprintf do? I'm willing to learn but would need a starting point.

      Hi RobertJ,

      The regex picks those two digits because they're the only ones preceded by a space.

      As for the rest: because the /e modifier is used on the substitution, the replacement part is evaluated as a Perl expression. sprintf is documented in sprintf: the first argument is the format specifier, in this case %i, aka %d: "a signed integer, in decimal", where 2.2 specifies a minimum width of 2 and a precision of 2 (personally, I would have written it as %02d, TIMTOWTDI). As for the argument to be formatted, $1 refers to the first capture group of the regex, in this case the two digits of the hour, from which 1 hour is subtracted. The formatted string returned by sprintf is then used as the substitution.

      Hope this helps,
      -- Hauke D

        Didn't notice the space (it is an actual character).

        The rest I was able to figure out from O'Reilley and a little Googling.

        Thanks for reminding me that " " is a character.