On Tue, May 11, 2004 at 05:28:13PM -0600, Jacob Fugal wrote:
> QuickBrownFox wrote:
> >Hey everybody,
> >
> >I'm using a regular expression for validation here at work that I wanted 
> >some advice on.  Specifically, it checks to see if the time is formatted 
> >correctly in the 12-hour format (hh:mm:ss (AM|PM)).  So far, this is 
> >what I've got:
> >
> >/^(0?[1-9]|1[0-2]):([0-5][0-9]):9[0-5][0-9]) (AM|PM)$/
>                                   ^
> Looks fine, except I think you missed a shift key (above the marker, if 
> that 9 is a (, then everything's fine). Although I'd relax the 
> requirement for seconds and allow variable whitespace:
> 
> /^(0?[1-9]|1[0-2]):([0-5][0-9])(:([0-5][0-9]))?\s*(AM|PM)$/

I'd also compress the AM|PM -> ([AP]M) ... slightly more efficient.

I'd also separate out the check to programming logic.  Regexes can get hairy
when you try to do a lot in them.  Especially in languages that arent' really
built around regexes.

> sub check_time
> {
>    # get input and check general format
> 
>    my $time = shift;
>    if ($time =~
>        /^(0?[1-9]|1[0-2]):([0-5][0-9])(:([0-5][0-9]))?\s*(AM|PM)$/)
>    {
>       # get parts and convert to 24 hours string w/o colons (default
>       # seconds to 0
> 
>       my ($hour, $min, $sec, $am_or_pm) = ($1, $2, $4, $5);
>       $hour += 12 if $am_or_pm eq 'PM';
>       $sec = 0 unless $sec;
>       my $new_time = $hour . $min . $sec;
> 
>       # make sure the time is between 8AM and 5PM (inclusive)
> 
>       return ($new_time ge '080000' and $new_time le '170000');
>    }
>    else { return 0; }
> }

<WARNING: Perl Hacker At Work>

If you're gonna do it that way, I'd change it to something like:

use Time::ParseDate; # Included in the default installation.

sub check_time {
  my ( $time, $start, $end ) = @_;

  my $s = parsedate( $start || '00:00:00' ) or return undef;
  my $e = parsedate( $end || '23:59:59' ) or return undef;

  my $t = parsedate( $time ) or return undef;

  return undef unless $s <= $t && $t <= $e;

  my @t = ( localtime( $t ) )[2,1,0];

  my $t[3] = $t[0] > 12 ?
    do { $t[0] -= 12 ; "PM" } :
    do { $t[0] = 12 if $t[0] == 0 ; "AM" };

  sprintf "%2d:%2d:%2d %s", @t;
}

That was fun.  Hmmm ... maybe a local Fun With Scripting Languages mailing
list (as opposed to Fun With Perl).

Alan

____________________
BYU Unix Users Group 
http://uug.byu.edu/ 
___________________________________________________________________
List Info: http://uug.byu.edu/cgi-bin/mailman/listinfo/uug-list

Reply via email to