First off, a few style related points to ponder:
- Be consistent with white space usage. Perl::Tidy is great for cleaning up code
- Don't use & to call subs, it doesn't do what you think. Use subName(...) instead.
- Don't use prototypes. They really don't do what you think.
- Use early exits to clean up error handling logic and remove levels of indentation.
I'd put the code into a subroutine to make testing easier. I'd also simplify the time matching regex and perform the range checking outside the regex. Something like:
#!/usr/bin/perl
use strict;
use warnings;
for my $test ('', '234-10:23', '0:0:1', '0:1', '24:60') {
my $fail = parseTime($test);
print "Failed parsing '$test': $fail\n" if $fail;
}
sub parseTime {
my ($inputTxt) = @_;
return "Bad input value" if !defined $inputTxt || !length $inputTx
+t;
$inputTxt =~ s/^\s+|\s+$//g;
return "Bad time string"
if $inputTxt !~ /^(?:(\d{1,3})-)?(?:(\d+):)?(\d+):(\d+)/;
my ($days, $hours, $mins, $secs) = map {$_ || 0} $1, $2, $3, $4;
return "Bad day count: $days" if $days > 366 && $days >= 0;
return "Bad hour value: $hours" if $hours > 23 && $hours >= 0;
return "Bad minutes value: $mins" if $mins > 59 && $mins >= 0;
return "Bad seconds value: $secs" if $secs > 59 && $secs >= 0;
my $totalSecs =
($days * 24 * 3600) + ($hours * 3600) + ($mins * 60) + $secs;
print "$inputTxt - ${totalSecs}s\n";
return;
}
Prints:
Failed parsing '': Bad input value
234-10:23 - 20218223s
0:0:1 - 1s
0:1 - 1s
Failed parsing '24:60': Bad seconds value: 60
True laziness is hard work