This code does not work in Y10k, but it should be good enough. The regular expression may be more strict, but if the date has already been confirmed (or will be confirmed in a new form), it does not matter.
use strict;
use warnings;
my @mon = qw/null JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC/;
my $d = "20080428";
$d =~ s/..(..)(..)(..)/$3-$mon[$2]-$1/;
print "date is now $d\n";
Or if you are crazy and want to check in regex (Perl 5.10 required):
use strict;
use warnings;
my @mon = qw/null JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC/;
my $d = join '', @ARGV;
$d =~ s/
^
(?:
# non-leap years and everything but 29th of Feb in leap years
(?:
1[6-9] (?<y> [0-9]{2}) |
[2-9][0-9] (?<y> [0-9]{2})
)
(?: #any month 1st through 28th
(?: (?<m> 0[1-9] | 1[0-2]) (?<d> 0[0-9] | 1[0-9] | 2[0-8]) )
| #or 30th of any month but 2
(?: (?<m>0[13-9] | 1[0-2]) (?<d> 30) )
| # or 31st of 1, 3, 5, 7, 8, 10, or 12
(?: (?<m>0[13578] | 1[02]) (?<d> 31) )
)
| # or 29th of Feb in leap years
(?:
(?: #centuries divisible by 4 minus the ones divisible by 100
16 |
[2468][048] |
[3579][26]
)
(?<y> 00)
| #or non-centuries divisible by 4
(?: 1[6-9] | [2-9][0-9] )
(?<y>
0[48] |
[2468][048] |
[13579][26]
)
)
(?<m> 02) (?<d> 29)
)
$
/$+{y}-$mon[$+{m}]-$+{d}/x or die "invalid date: $d";
print "date is now $d\n";
source
share