3

I am trying to validate the time in

00:00 to 11:59 ends with AM OR PM

I was tring some regex,but not getting succesful to validate time. My java script function is

function verifydata( incoming ) {
var re = (1[012]|[1-9]):[0-5][0-9](\\s)?(?i)(am|pm);
if(incoming.time.value != '' && !incoming.time.value.match(re)) 
{
alert("Invalid time format: " + incoming.time.value);
}
}

its not working

I tried this also, not working

var re = /^(?:[01][0-9]|2[0-3]):[0-5][0-9]$/;

let me where I am going wrong?

10
  • what's the source of the string? Commented Jul 22, 2013 at 22:21
  • string is being entered in textbox by user Commented Jul 22, 2013 at 22:22
  • What does ?i do? (Also, you know (am|pm) will only match lower case letters. Right?) Your regex won't match "00:00" because it only allows "0:00". Commented Jul 22, 2013 at 22:22
  • 1
    @Lee Meador: That is a way of specifying case-insensitive matching in PCRE (the regex library PHP uses); however, JavaScript does not support that. Commented Jul 22, 2013 at 22:23
  • @leemeador, not having so much knowledge of regex..just searched and tried a lot of regex....in case of( am|pm ), we can add (AM|PM) also ? Commented Jul 22, 2013 at 22:23

3 Answers 3

7

Try this

function testTime( time ) {
  var regex = /^([0-1][0-9])\:[0-5][0-9]\s*[ap]m$/i;
  var match = time.match( regex );
  if ( match ) {
    var hour  = parseInt( match[1] );
    if ( !isNaN( hour) && hour <= 11 ) {
      return true;
    }
  }
  return false;
}

testTime( '12:00 AM' ); // false  
testTime( '11:59 PM' ); // true  
testTime( '00:00 AM' ); // true  
testTime( '00:00am' ); // true  
testTime( '10:00pm' ); // true  
Sign up to request clarification or add additional context in comments.

Comments

2

JavaScript does not support (?i), yet it does support the i flag to enable case-insensitive matching for the entire regexp. Also, in regexp literals (as opposed to normal string literals), do not escape the backslash when it is used as a metacharacter:

var re = /^(1[012]|[1-9]):[0-5][0-9]\s?(am|pm)$/i;

2 Comments

This is the better answer, though a bit inconsistent with the capturing groups... Everything explained with demo: regex101.com/r/oB7hJ2
The original code was already inconsistent yet placed the \s in its own unnecessary group. To be consistent, simply add a ?: after each (. Then there would be no capturing groups.
-1

I'm not a fan of regular expressions for everything - in particular, I dislike them for number ranges.

Assuming some lateral in how the function is written:

 // regex used for "high level" check and extraction
 // matches "hh:mmAM", "hh:mm", "hh:mm PM", etc
 var matches = inp.match(/^(\d\d):(\d\d)\s?(?:AM|PM)?$/)
 if (matches && matches.length == 3) {
   var h = parseInt(matches[1], 10)
   var m = parseInt(matches[2], 10)
   // range checks done in code after getting numeric value
   return h >= 1 && h <= 12 && m >= 0 && m <= 59
 } else {
   return false
 }

6 Comments

not working..nothing happens :(
@user2608523 In this case "nothing happens" meant "it returned an incorrect value". I've fixed the code which was a bug in the usage of matches.
i am testing it using alert..it is goin in my function but not going in if or else part
@user2608523 See very latest update. Double fail on my part but now works. That being said, this doesn't answer the why doesn't this work part of the question; I'm merely proposing that regular expressions don't need to be used exclusively. You'll have to use the /i modifier or otherwise change (?AM|PM) for it to be case-insensitive. Alternatively, if you allow more relaxed input, consider: inp.match(/^(\d\d?):(\d\d)(?\D|$)/ which doesn't even both to match any trailing AM, pm, a.m. or whatever.
i am using incoming.time.value.match instead of inp.match, because my value is coming from textbox anemd as time..is that ok with me? or i am doing mistake in that?
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.