If you're doing this just for the sake of the exercise, I guess I'll enourage you. However there are already
many many date/time modules that are available to you that have all previously dealt with the problems of parsing datetime strings.
Firstly, a personal preference: I hate seeing all variables declared at the top. Declare them as you use them.
The second thing that strikes me in your code is your declaration of your hash. You don't need to assign any value at all. Something like my %hash; works perfectly. Or if you prefer: my %hash = ();. That way you won't have to delete the key later.
Then there's no need to use @old as your <DATA> file handle can work inside the foreach:
foreach $old(<DATA>) { ... }
Also your
cvrt_mon_lcl subroutine would be better as a hash:
my %month_number;
@month_number{qw/Jan Feb Mar Apr May ... Dec/} = (0 .. 11);
print $month_number{Jan};
# 0
Back to all those modules to select from, I'm a
DateTime fan (and developer) so I'll give you my DateTime solution:
use DateTime;
use DateTime::Format::Strptime;
my $parser = DateTime::Format::Strptime->new(
pattern => '%a %b %d %T EST %Y', # see the docs for the patterns
locale => 'en_US', # to get the month and day names to parse
time_zone => 'America/New_York',
);
my $now = DateTime->now(time_zone => 'America/New_York');
foreach (<DATA>) {
my ($dt) = $_ =~ /^(.+?)\s:\s/;
$dt = $parser->parse_datetime($dt); # turn the string into a dateti
+me
print $_
if (($dt < $now)
and ($dt->add(days => 45) > $now))
}
__DATA__
Fri Dec 3 23:07:21 EST 2004 : Depth is : 234
Sat Dec 4 00:07:29 EST 2004 : Depth is : 123
Sun Dec 5 03:07:32 EST 2004 : Depth is : 144
Tue Feb 8 05:21:18 EST 2005 : Depth is : 11
Sat Feb 26 14:13:12 EST 2005 : Depth is : 4567
Fri Mar 11 17:09:38 EST 2005 : Depth is : 265
Sat Mar 12 07:07:27 EST 2005 : Depth is : 1654
Sat Mar 26 07:07:27 EST 2005 : Depth is : 1654
Some notes:
- The pattern could use %Z instead of 'EST' in which case it wouldn't need to specifically declare the time zone. However 'EST' is an ambiguous zone and so we can't use it.
- We add 45 days to the datetime and then check if it's greater than now rather than just subtracting it from now and checking that the difference is over 45 days because of the problems inherrent with date math ('daylight savings'/leap years/seconds etc.)
- I also check that it isn't a future date, but if this is log parsing that shouldn't be a problem
- If you only need day precision see the 'truncate' method in the DateTime documentation.
- DateTime is the only set of modules that properly handle time zones and daylight savings (as well as handling international locales).
Cheers!
Rick
If this is a root node: Before responding, please ensure your clue bit is set.
If this is a reply: This is a discussion group, not a helpdesk ... If the discussion happens to answer a question you've asked, that's incidental.