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
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.
| [reply] [d/l] |
|
| [reply] |
|
| [reply] |
|
Re: Month '-1' out of range 0..11
by kennethk (Abbot) on Mar 18, 2014 at 15:32 UTC
|
| [reply] [d/l] [select] |
|
#!/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?
| [reply] [d/l] |
|
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.
| [reply] [d/l] [select] |
|
|
|
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.
| [reply] [d/l] |
|
|