Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java conditional regex to check 24 hour time?‽

I am doing the following programming exercise: regex validation of 24 hours time. The statement is:

Write a regex to validate a 24 hours time string. See examples to figure out what you should check for:

Accepted: 01:00 - 1:00

Not accepted:

24:00

You should check for correct length and no spaces.

I would like to ask, why the following regular expression, matches 24:00

public class RegexValidation {
  public static boolean validateTime(String time) {
    System.out.println("time: "+time);
    return time.matches("(?:^[2])[0123]+:[0-5]+[0-9]|[0-9]+:[0-5]+[0-9]");
  }
}

Because I thought it was expressing: "If string starts with 2, then it should continue with [0-3] (one or more) : [0-5] one or more and [0-9]. Else it continues with [0-9] one or more : [0-5] one or more and [0-9]."

The tests are:

import org.junit.Test;
import static org.junit.Assert.*;

public class RegexValidationTest {

  @Test
  public void test1() {
    assertTrue(RegexValidation.validateTime("01:00"));
  }

  @Test
  public void test2() {
    assertTrue(RegexValidation.validateTime("1:00"));
  }

  @Test
  public void test3() {
    assertTrue(RegexValidation.validateTime("00:00"));
  }

  @Test
  public void test4() {
    assertFalse(RegexValidation.validateTime("13:1"));
  }

  @Test
  public void test5() {
    assertFalse(RegexValidation.validateTime("12:60"));
  }

  @Test
  public void test6() {
    assertFalse(RegexValidation.validateTime("24:00"));
  }
}

In addition I wrote the following solution, which passes the tests:

public class RegexValidation {
  public static boolean validateTime/*⌚*/(String time) {
    if(time.matches("[\\d]+:[\\d]{2}")){
      String[] times = time.split(":");
      int hours = Integer.parseInt(times[0]);
      int minutes = Integer.parseInt(times[1]);
      return hours < 24 && minutes < 60;
    }
    return false;
  }
}

I have also read:

  • Conditional Regular Expression in Java?
  • https://www.regular-expressions.info/conditional.html
  • understanding regex if then statements

Finally the question is, why in the first code the regex matches 24:00?‽

like image 229
Enoy Avatar asked Jan 26 '26 19:01

Enoy


1 Answers

This is because of the | present. The alternative after this, [0-9]+ matches any digit from 1 to 9, and breaks the required output.

The following regex should work,

^([01]\d|[0-9]|2[0-3]):?([0-5]\d)$

If the : is not optional, remove the ?

^([01]\d|[0-9]|2[0-3]):([0-5]\d)$

Also verified on jshell

jshell> var pattern = Pattern.compile("^([01]\\d|[0-9]|2[0-3]):?([0-5]\\d)$");
pattern ==> ^([01]\d|[0-9]|2[0-3]):?([0-5]\d)$

jshell> pattern.matcher("23:01").matches();
$2 ==> true

jshell> pattern.matcher("24:01").matches();
$3 ==> false

jshell> pattern.matcher("00:01").matches();
$4 ==> true

jshell> pattern.matcher("09:01").matches();
$5 ==> true

jshell> pattern.matcher("9:01").matches();
$6 ==> true

jshell> pattern.matcher("12:00").matches();
$7 ==> true
like image 144
Adwait Kumar Avatar answered Jan 29 '26 08:01

Adwait Kumar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!