Database Reference
In-Depth Information
it applicable in more contexts. For example, you can use it to check dates like
12
Febru
ary
2003
by mapping the month to its numeric value before calling
is_valid_date()
.
If
is_valid_date()
took a string argument assumed to be in a specific date format, it
would be much less general.
is_valid_date()
uses a subsidiary function
days_in_month()
to determine the num‐
ber of days in the month represented by the date.
days_in_month()
requires both the
year and the month as arguments because if the month is 2 (February), the number of
days depends on whether the year is a leap year. This means you
must
pass a four-digit
year value: as discussed in
Recipe 6.18
, two-digit years are ambiguous with respect to
the century, which makes proper leap-year testing impossible. The
days_in_month()
and
is_leap_year()
functions are based on techniques taken from that recipe:
sub
is_leap_year
{
my
$year
=
$_
[
0
];
return
(
$year
%
4
==
0
)
&&
(((
$year
%
100
)
!=
0
)
||
(
$year
%
400
)
==
0
);
}
sub
days_in_month
{
my
(
$year
,
$month
)
=
@_
;
my
@day_tbl
=
(
31
,
28
,
31
,
30
,
31
,
30
,
31
,
31
,
30
,
31
,
30
,
31
);
my
$days
=
$day_tbl
[
$month
-
1
];
# add a day for Feb of leap years
$days
++
if
$month
==
2
&&
is_leap_year
(
$year
);
return
$days
;
}
To perform validity checking on time values, a similar procedure applies: verify that the
value matches a time pattern and break it into components, then perform range-testing
on the components. For times, the ranges are 0 to 23 for the hour, and 0 to 59 for the
minute and second. Here is a function
is_24hr_time()
that checks for values in 24-
hour format and returns the components:
sub
is_24hr_time
{
my
$s
=
$_
[
0
];
return
undef
unless
$s
=~
/^(\d{1,2})\D(\d{2})\D(\d{2})$/
;
return
[
$1
,
$2
,
$3
];
# return hour, minute, second
}
The following
is_ampm_time()
function is similar but looks for times in 12-hour format
with an optional AM or PM suffix, converting PM times to 24-hour values:
sub
is_ampm_time
{
my
$s
=
$_
[
0
];