in reply to hash, Date:Calc use - seeking improvements

Also, as the conversion of mday and non-conversion of month and year (at lines 34-36) demonstrate, I just haven't "got" something in the litt re Time::Local.

Well as it turns out, this little bit from your code does confirm that opinion:

#... $mday = ( $2 - 1 ); # mday is in range 0-30 for timelocal #...
No. Actually, the "mday" value used by timelocal should range between 1 and 31, just like the "mday" value returned by localtime.

(An interesting feature of Time::Local is that you can give it out-of-range values for some fields, and it will do the "right" thing; e.g. give it $mon=1 (Feb) and $mday=30, and it will give you epoch seconds for March 2 (or March 1, if it's a leap year). So the fact that you were passing "wrong" values for mday meant that you got unexpected retuen values, instead of some carp/croak/die behavior.)

As for the "year" value, timelocal is quite clever and forgiving about that -- if you haven't read the details about this in "perldoc Time::Local", you should.

Which leads me to the obscure detail in your initial regex that will need to be modified less than six years from now; surely you're not so young that you never heard of "Y2K bugs" -- you've got a "Y2K+10" bug. (But I know you'll be able to fix it in time. ;)

I would just use a hash to get from month name to month number. Setting it up can be tedious, but less so than devoting a whole subroutine to the task. Here is probably the least offensive way, all things considered:

my @mon_names = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/; my %mnth_str2digit = map { $mon_names[$_] => $_ } (0..$#mon_names); # or, if map is "unintelligible to rookies", use a for loop: my %mnth_str2dgt; for ( 0..$#mon_names ) { $mnth_str2digit{$mon_names[$_]} = $_; ]
This way, you just use the 3-letter month name to do a hash look-up for the month number, rather than calling a sub that alters the value of a global (which is considered bad form).

Apart from all that, I tend to agree with the first reply: if you're just doing this for the sake of practice with regexes and particular core modules, or if you really are in a situation where the presence of more powerful non-core modules simply can't be assured or controlled, that's fine -- knock yourself out.

But if relevant non-core modules are present, or you have the ability to install them as needed, it can often be a mistake to avoid using them for reasons like "my task is simple enough that I don't need a module" or "figuring out how to use the module will take too long" or "it'll make my script too complicated/difficult for me or others to follow". Regardng the first reason, even if it's true now, it might not be true later (e.g. when you get new/different data next week); as for the others, they tend to be imaginary and contrary to fact.

I happened to choose Date::Manip as a solution when I replied to grep for last 45 days -- it was just the first one that came to mind, and it was installed already, though I hadn't really used it at all. Starting cold, it didn't take more that 10 minutes to read enough of the man page and put together a 5-line script to solve the stated task, and I don't think the result was all that cryptic. (Okay, newbies would spend more time reading the man page and puzzling out how to use the module in a script, but still, they'd fare better that way than without the module.)