Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Month '-1' out of range 0..11

by swissknife (Sexton)
on Mar 18, 2014 at 15:18 UTC ( [id://1078795]=perlquestion: print w/replies, xml ) Need Help??

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

Hello Experts,
#! /usr/bin/perl use strict; use Time::Local; use Math::BigFloat; Math::BigFloat->precision(0); my $inpath = "/tmp/IN"; my @inputfiles = &GetINDirFiles($inpath); print "@inputfiles \n"; sub GetINDirFiles { my ($path) = @_; my $min_age = 0.25/24; opendir DIR, $path or die $!; # my @files = readdir DIR; my @files=grep {!/\_ACK|_\d+_\d+\.xml/ && (&UTCtoLocal("$path/$_")) + } readdir DIR; closedir DIR; return(@files); } sub UTCtoLocal { my ($filetoread) = @_; open (INFILE, "<$filetoread") or die "$!"; my @ActTime = map {/"(.*?)"/} grep {/MessageDateTime/} (<INFILE>); my $iso_time = join("", @ActTime); my $expected_epoch = 1 * 60 * 60 + 1 * 60 + 1; my ($date, $time) = split /T/ => $iso_time; my ($year, $mon, $mday) = split /-/ => $date; my $currenttime = time; # get current time from system (epoch time) my $threshold = 900; $year -= 1900; $mon -= 1; my ($hour, $min, $sec) = split /:/ => $time; my $nsec = chop($sec); my $mtime = timegm($sec, $min, $hour, $mday, $mon, $year); my $diff = ($currenttime - $mtime); if ($diff > $threshold) { return ($filetoread); } }

What i am trying to achieve here is list all the files from directory /tmp/IN which does node have _ACK in the name (which is no issue) and next read the file and look for a value of MessageDateTime (This is how it appears in file <MessageDateTime v="2014-03-18T15:41:14Z" />) and if this time is 15 minute less from current time, list only such files

.

When i execute it gives me below error.

Month '-1' out of range 0..11 at listfiletest.pl line 39

Could someone let me know where i am doing wrong? swissknife

Replies are listed 'Best First'.
Re: Month '-1' out of range 0..11
by Limbic~Region (Chancellor) on Mar 18, 2014 at 15:32 UTC
    swissknife,
    Have you checked the values are what you think they are?
    print "$sec, $min, $hour, $mday, $mon, $year\n";
    There are many more comments unrelated to your problem I could make:
    • Using 2-arg open
    • Using bareword file handle
    • Using &subroutine() when not necessary
    • Etc.
    But I am betting you will solve your problem simply by inspecting the values of your variables.

    Cheers - L~R

      I think issue is because of readdir read hidden files as well, which are then used in sub and it failes. what can be done to ignore hidden files in readdir?

        swissknife,
        I think issue is because of readdir read hidden files as well, which are then used in sub and it failes. what can be done to ignore hidden files in readdir?

        Why are you guessing? I suggested printing the values because there is a pretty big hint they aren't what you think they are. You should also print the file name (filetoread) and know that is your problem before taking action.

        Cheers - L~R

Re: Month '-1' out of range 0..11
by kennethk (Abbot) on Mar 18, 2014 at 15:32 UTC
    So, tracing the value back, $mon gets a value of -1 on line 35, which means it was numerically 0 from line 30. My guess, since you don't have warnings on, is that your content is different than you think going back to line 26, and so $mon is undefined going into the decrement. Can't be sure without you input file, but based on what you've posted, I'm guessing the split on 29 splits on the T in MessageDateTime rather than the T in the iso date.

    See Basic debugging checklist and Use strict warnings and diagnostics or die.


    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

      Kenneth - Thanks for response. I doubt that it is issue with split. I have another simple codes which works well.

      #!/usr/bin/perl -w use strict; use Time::Local; my $filename = "/tmp/IN/m1.xml"; my $finaltime = &UTCtoLocal($filename); print "$finaltime \n"; sub UTCtoLocal { my ($filetoread) = @_; open (INFILE, "<$filetoread") or die "$!"; my @ActTime = map {/"(.*?)"/} grep {/MessageDateTime/} (<INFILE>); my $iso_time = join("", @ActTime); my $expected_epoch = 1 * 60 * 60 + 1 * 60 + 1; my ($date, $time) = split /T/ => $iso_time; my ($year, $mon, $mday) = split /-/ => $date; $year -= 1900; $mon -= 1; my ($hour, $min, $sec) = split /:/ => $time; my $nsec = chop($sec); my $mtime = timegm($sec, $min, $hour, $mday, $mon, $year); return ($mtime); }

      Based on these codes i prepared another one in OP as that is my main objective.

      reagarding the inputfile, i have already provided the line which has this date and keyword used in the grep command.

      any further clue?

        Did you try printing the value in $date on line 29? The answer is that some of the values are not what you think, because the following code works fine:
        #! /usr/bin/perl use strict; use warnings; use Time::Local; my $iso_time = '2014-03-18T15:41:14Z'; my $expected_epoch = 1 * 60 * 60 + 1 * 60 + 1; my ($date, $time) = split /T/ => $iso_time; my ($year, $mon, $mday) = split /-/ => $date; my $currenttime = time; # get current time from system (epoch time) my $threshold = 900; $year -= 1900; $mon -= 1; my ($hour, $min, $sec) = split /:/ => $time; my $nsec = chop($sec); my $mtime = timegm($sec, $min, $hour, $mday, $mon, $year);
        However, without your actual input file, I'm just guessing. Adding warnings and following the advice in Basic debugging checklist will help you track down the issue. Alternatively, I could help you debug if you posted your input file, wrapped in <code> tags.

        #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Month '-1' out of range 0..11
by t_rex_joe (Sexton) on Mar 18, 2014 at 17:42 UTC
    swissknife, Here's a high level design for your code regards to dates/times.. By using the "Date::Manip" module you can parse many date formats and calculations..
    #!/usr/bin/perl use Date::Manip; $val = "<MessageDateTime v=\"2014-03-18T15:41:14Z\" \/\>"; ($ftime) = ($val =~ /\=\"(.*)\"/); print "FTIME: \"$ftime\"\n"; $ftime =~ s/\T/ /; print "FTIME: \"$ftime\"\n"; $parse = &ParseDate($ftime); print "PARSE: \"$parse\"\n"; $eptime = UnixDate($parse, "%s"); print "EPTIME: \"$eptime\"\n"; $ct = 0; $ct = 15; $septime = undef; $time = undef; $septime = UnixDate(ParseDate("$ct minutes ago"), "%s"); print "$ct MINUTES AGO: \"$septime\"\n"; if($eptime > $septime) { print "EPTIME: \"$eptime\" IS MORE THEN SEPTIME \"$septime\".. KEEP +FILE\n"; } else { print "EPTIME: \"$eptime\" IS -NOT- MORE THEN SEPTIME \"$septime\".. + NEXT\n"; } OUTPUT: FTIME: "2014-03-18T15:41:14Z" FTIME: "2014-03-18 15:41:14Z" PARSE: "2014031811:41:14" EPTIME: "1395157274" 15 MINUTES AGO: "1395163449" EPTIME: "1395157274" IS -NOT- MORE THEN SEPTIME "1395163449".. NEXT
    If the time in the file is more then 15 minutes ago keep the file else next. NOTE: I prefer nowadays to use date::manip due to flexibility.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1078795]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-26 08:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found