use Time::Piece

	I can not seem to send Time::Piece any syntax it likes.

	The file I am reading sends a time stamp that should
conform to RFC822 date stamps.  An example of a stamp follows:

main::(lwx:204):            my @obtime =3D split( /\,+/, $data->{observati=
on_time_
rfc822} );
  DB<2> print $obtime[1]
 30 Oct 2018 20:53:00 -0500
  DB<2> n
main::(lwx:205):            my $t1 =3D Time::Piece->strptime( '$obtime[1]'=
, '%D %b
 %H:%M:%S %z' );
  DB<2> n
Error parsing time at /usr/lib/i386-linux-gnu/perl/5.24/Time/Piece.pm line=
 481.
 at /usr/lib/i386-linux-gnu/perl/5.24/Time/Piece.pm line 481.
        Time::Piece::strptime("Time::Piece", "\$obtime[1]", "%D %b %H:%M:%=
S %z")
 called at lwx line 205

The code that caused all that follows:

    my @obtime =3D split( /\,+/, $data->{observation_time_rfc822} );
    my $t1 =3D Time::Piece->strptime( '$obtime[1]', '%D %b %H:%M:%S %z' );

	Another thing I tried was just
    my $t1 =3D Time::Piece->strptime( '$obtime[1]', '%z' );

	The man page for strptime lists all the possible %flags
one can send and the last one is %z for RFC822

       %z     An RFC-822/ISO 8601 standard timezone specification.

I was not sure if that meant it would pull in all the fields
shown above.  If it had, I wouldn't be posting this message so I
tried the longer form

    my $t1 =3D Time::Piece->strptime( '$obtime[1]', '%D %b %H:%M:%S %z' );

There is that -500 offset from utc, soon to become a -600 this
Sunday.

The following code will demonstrate the only outcome I have been
able to get.  Those of you who followed earlier messages in the
thread about time stamps will recognise this code which now has a
few more lines and the data dumper is commented out but it
demonstrates what is happening.

	If there is some way to see what Time::Piece thinks I am
trying to tell it to do then one might be able to figure out what
is wrong but a miss is the same as close so I can't tell if I am
getting warm.

	Thanks for any ideas.

Martin McCormick

Code follows:

#!/usr/bin/perl -w
use strict;
use warnings::unused;
use Data::Dumper;
use XML::Simple;
use File::Basename;
use Cwd;
use File::stat;
use Time::Local;
use Time::Piece;
my $homedir =3D "/tmp";
my @t       =3D localtime(time);
my $utcsec  =3D timelocal(@t);
my $wxfile  =3D 'display.php?stid=3DKSWO';

#I want that file to end up in a specific directory so:
my $wxpath                =3D $homedir . "/" . $wxfile;
my $day                   =3D 86400;                           #seconds
my $hour                  =3D 3600;
my $gmt_offset_in_seconds =3D timegm(@t) - timelocal(@t);
my $tzoffset              =3D $gmt_offset_in_seconds / 3600;

#many thanks to whoever wrote the quick way to determine TZ
#offset from utc

my $wxlast_update_time;

#Grab conditions from NOAA if the file is stale or missing.
if ( !stat($wxpath) ) {    #The file is not there.
    system(
        "curl -s -o $wxpath 'http://w1.weather.gov/xml/current_obs/$wxfile=
'");

    #Change the mtime to a quarter past last hour.
    my $when =3D timelocal( 0, 15, $t[2], $t[3], $t[4], ( $t[5] - 100 ) );
    utime $when, $when, "$wxpath";
}         #The file is not there.
else {    #what normally happens
    my $wxstatRef =3D stat($wxpath);
    $wxlast_update_time =3D $wxstatRef->mtime();
    my $wxage =3D ( $utcsec - $wxlast_update_time );
    if ( $wxage >=3D $hour ) {    #File needs to be refreshed.

        #The file should not be more than 3600 seconds old.
        system(
            "curl -s -o $wxpath 'http://w1.weather.gov/xml/current_obs/$wx=
file'"
        );

        #Change the mtime to a quarter past.
        my $when =3D timelocal( 0, 15, $t[2], $t[3], $t[4], ( $t[5] - 100 =
) );
        utime $when, $when, "$wxpath";
    }    #File needs to be refreshed.
}    #what normally happens

# create object
my $xml =3D new XML::Simple;

# read XML file
my $data =3D $xml->XMLin("$wxpath");

#print Dumper($data);

my @obtime =3D split( /\,+/, $data->{observation_time_rfc822} );
my $t1 =3D Time::Piece->strptime( '$obtime[1]', '%D %b %H:%M:%S %z' );
exit(0);
0
martin
10/31/2018 3:24:26 AM
perl.beginners 29318 articles. 3 followers. Follow

6 Replies
15 Views

Similar Articles

[PageSpeed] 38

On 10/30/18 11:24 PM, Martin McCormick wrote:
> 	I can not seem to send Time::Piece any syntax it likes.
>
> 	The file I am reading sends a time stamp that should
> conform to RFC822 date stamps.  An example of a stamp follows:
>
> main::(lwx:204):            my @obtime = split( /\,+/, $data->{observation_time_
> rfc822} );
>    DB<2> print $obtime[1]
>   30 Oct 2018 20:53:00 -0500

whenever i print stuff for debugging i put it in [] or similar so i can 
see white space or other odd things.

try print "[$obtime[1]]" and see what is really there.
>    DB<2> n
> main::(lwx:205):            my $t1 = Time::Piece->strptime( '$obtime[1]', '%D %b
>   %H:%M:%S %z' );

well, that will always fail. you are parsing the actual string 
$obtime[1] and not its value. single quote are not allowing any 
interpolation. you don't even need quotes to pass a scalar value and it 
is usually a bug.
>    DB<2> n
> Error parsing time at /usr/lib/i386-linux-gnu/perl/5.24/Time/Piece.pm line 481.
>   at /usr/lib/i386-linux-gnu/perl/5.24/Time/Piece.pm line 481.
>          Time::Piece::strptime("Time::Piece", "\$obtime[1]", "%D %b %H:%M:%S %z")
>   called at lwx line 205
similar bug. you escape the $ so the timestamp value is not 
interpolated. you are parsing the wrong  string.


> 	If there is some way to see what Time::Piece thinks I am
> trying to tell it to do then one might be able to figure out what
> is wrong but a miss is the same as close so I can't tell if I am
> getting warm.
just stop with the extra quotes (single or double). just pass $obtime[1] 
to strptime. i am guessing you are passing in Time::Piece as the class 
in what would be an OO call. stick to the normal OO style there.


uri
0
uri
10/31/2018 3:34:16 AM
Uri Guttman <uri@stemsystems.com> writes:
> whenever i print stuff for debugging i put it in [] or similar so i can 
> see
> white space or other odd things.
> 
> 
> try print "[$obtime[1]]" and see what is really there.

  DB<2> print "[$obtime[1]]"
[ 31 Oct 2018 06:53:00 -0500]

I do believe that the leading white space before the 3 should not
be there.

#get rid of leading spaces.
    $obtime[1] =~ s/^\s+//;
#get rid of trailing spaces.
    $obtime[1] =~ s/\s+$//;

  DB<2> print "[$obtime[1]]"

[31 Oct 2018 06:53:00 -0500]

One of the oldest admonitions in the book says "Never trust data."

	That leading space came from the split of a , separated
string and it completely got by me.

I'd like to say that it's working but not yet.  There seems to be
nothing wrong with the string now.

my $t1 = Time::Piece->strptime("$obtime[1], %d %b %Y %H:%M:%S %z");

Still the parse error.

	Right now, I do have  both

use Time::Local;
use Time::Piece;

in the program and Time::Piece is supposed to replace many of the
functions of Time::Local.  If I comment out Time::Local, a
reference to gntime breaks.

	Could this be causing Time::Piece not to work?

Martin McCormick
0
martin
10/31/2018 8:29:14 PM
On Oct 31, 2018, at 1:29 PM, Martin McCormick <martin.m@suddenlink.net> =
wrote:
>=20
>=20
> I'd like to say that it's working but not yet.  There seems to be
> nothing wrong with the string now.
>=20
> my $t1 =3D Time::Piece->strptime("$obtime[1], %d %b %Y %H:%M:%S =
%z=E2=80=9D);

strptime is a method with two arguments:  string to be parsed, format to =
be used for parsing. You have one argument: a double-quoted string.

my $t1 =3D Time::Piece->strptime($obtime[1], "%d %b %Y %H:%M:%S %z=E2=80=9D=
);
0
jimsgibson
10/31/2018 8:58:56 PM
On 10/30/2018 10:24 PM, Martin McCormick wrote:
> 	I can not seem to send Time::Piece any syntax it likes.
>
> 	The file I am reading sends a time stamp that should
> conform to RFC822 date stamps.  An example of a stamp follows:
>
> main::(lwx:204):            my @obtime = split( /\,+/, $data->{observation_time_
> rfc822} );
>    DB<2> print $obtime[1]
>   30 Oct 2018 20:53:00 -0500
>    DB<2> n
> main::(lwx:205):            my $t1 = Time::Piece->strptime( '$obtime[1]', '%D %b
>   %H:%M:%S %z' );
>    DB<2> n
> Error parsing time at /usr/lib/i386-linux-gnu/perl/5.24/Time/Piece.pm line 481.
>   at /usr/lib/i386-linux-gnu/perl/5.24/Time/Piece.pm line 481.
>          Time::Piece::strptime("Time::Piece", "\$obtime[1]", "%D %b %H:%M:%S %z")
>   called at lwx line 205
>
> The code that caused all that follows:
>
>      my @obtime = split( /\,+/, $data->{observation_time_rfc822} );
>      my $t1 = Time::Piece->strptime( '$obtime[1]', '%D %b %H:%M:%S %z' );
>
> 	Another thing I tried was just
>      my $t1 = Time::Piece->strptime( '$obtime[1]', '%z' );
>
> 	The man page for strptime lists all the possible %flags
> one can send and the last one is %z for RFC822
>
>         %z     An RFC-822/ISO 8601 standard timezone specification.
>
> I was not sure if that meant it would pull in all the fields
> shown above.  If it had, I wouldn't be posting this message so I
> tried the longer form
>
>      my $t1 = Time::Piece->strptime( '$obtime[1]', '%D %b %H:%M:%S %z' );
>
> There is that -500 offset from utc, soon to become a -600 this
> Sunday.
>
> The following code will demonstrate the only outcome I have been
> able to get.  Those of you who followed earlier messages in the
> thread about time stamps will recognise this code which now has a
> few more lines and the data dumper is commented out but it
> demonstrates what is happening.
>
> 	If there is some way to see what Time::Piece thinks I am
> trying to tell it to do then one might be able to figure out what
> is wrong but a miss is the same as close so I can't tell if I am
> getting warm.
>
> 	Thanks for any ideas.
>
> Martin McCormick
>

None of your arguments are right. For one, you are using the '%D' flag 
which is the same as saying '%m/%d/%y'

This works fine from a quick command line test:
perl -e 'use Time::Piece; $t = "30 Oct 2018 20:53:00 -0500"; print 
Time::Piece->strptime( $t, "%d %b %Y %H:%M:%S %z" );'

Wed Oct 31 01:53:00 2018

But notice since you specified '%z', that that offset was added to the 
returned time... That might be what you want, or it might not be. And 
also note Time::Piece->strptime returns an object that is set to UTC 
whereas localtime->strptime returns an object not in UTC. If you really 
want to get crazy with parsing times, DateTime is usually recommended: 
https://metacpan.org/pod/DateTime or just 
https://metacpan.org/pod/DateTime::Format::Strptime

--Samuel Smith
0
perl
10/31/2018 10:25:08 PM
Sam <perl@net153.net> writes:
> 
> 
> 
> None of your arguments are right. For one, you are using the '%D' flag
> which is the same as saying '%m/%d/%y'
> 
> 
> This works fine from a quick command line test:
> 
> perl -e 'use Time::Piece; $t = "30 Oct 2018 20:53:00 -0500"; print
> Time::Piece->strptime( $t, "%d %b %Y %H:%M:%S %z" );'
> 
> 
> Wed Oct 31 01:53:00 2018
> 
> 
> But notice since you specified '%z', that that offset was added to the
> returned time... That might be what you want, or it might not be. And also
> note Time::Piece->strptime returns an object that is set to UTC whereas
> localtime->strptime returns an object not in UTC. If you really want to 
> get
> crazy with parsing times, DateTime is usually recommended: https://
> metacpan.org/pod/DateTime or just https://metacpan.org/pod/
> DateTime::Format::Strptime
> 
> 
> --Samuel Smith

	Thank you.  This turned out to be a comedy of errors on
my part.  It seems I may have stumbled across the correct way to
call the function but didn't realize it because of the wrong
arguments you saw.  I figured the %D issue out but, by that time,
I had messed around with things long enough that I forgot the ,
which separates the two arguments to that method must not be part
of the quoted string so even when the %variables were right, the
call would never work the way I had it.

	Another poster pointed this out and it now works fine.

	Thanks to all who helped.

Martin McCormick
0
martin
11/1/2018 10:50:59 AM
Jim Gibson <jimsgibson@gmail.com> writes:
> On Oct 31, 2018, at 1:29 PM, Martin McCormick <martin.m@suddenlink.net> 
> wrote:

> > my $t1 = Time::Piece->strptime("$obtime[1], %d %b %Y %H:%M:%S %z”);
> 
> strptime is a method with two arguments:  string to be parsed, format to 
> be used for parsing. You have one argument: a double-quoted string.
> 
> my $t1 = Time::Piece->strptime($obtime[1], "%d %b %Y %H:%M:%S %z”);

Thank you!  I forgot to keep that in mind.  As I kept trying
to get it to work and ended up with the , that separates the
arguments inside the whole string.  I may have even had it right
once but that may have been when at least one %variable was set
to the wrong case which would have made the correct format also
fail but for different reasons.  %d should have been the first
field which is the day of the month and instead, I had %D which
is a specific United States way of expressing a date 

	I know we all have our stupid moments but sometimes, I wish
I didn't have so many.

	Now, $t1 shows a nice representation of the UTC date that
the web server stamped the XML file with.

Martin McCormick
0
martin
11/1/2018 10:55:26 AM
Reply: