Update: Made space before AM/PM optional, since you sometimes see 9:45am
. Also added word boundary check.
Assuming you might want to do the check more than once, it's better to precompile the regular expression.
String timeExpr = "\\b" + // word boundary
"(?:[01]?[0-9]|2[0-3])" + // match 0-9, 00-09, 10-19, 20-23
":[0-5][0-9]" + // match ':' then 00-59
"(?! ?[ap]m)" + // not followed by optional space, and 'am' or 'pm'
"\\b" + // word boundary
"|" + // OR
"\\b" + // word boundary
"(?:0?[0-9]|1[0-1])" + // match 0-9, 00-09, 10-11
":[0-5][0-9]" + // match ':' and 00-59
" ?[ap]m" + // match optional space, and 'am' or 'pm'
"\\b"; // word boundary
Pattern p = Pattern.compile(timeExpr, Pattern.CASE_INSENSITIVE);
Note the "not followed by ' am' or ' pm'", otherwise it would match 17:00 PM
.
You can test it like this:
String str = "The current time in London is 6:00 PM, what is the time in Toronto?";
if (p.matcher(str).find()) {
System.out.println("Has time");
} else {
System.out.println("Has no time");
}
Or a more complex example that actually extracts the times:
String str2 = "When it is 6:00 PM in London, is it 14:00 in Toronto?";
Matcher m = p.matcher(str2);
if (! m.find())
System.out.println("Has no time");
else
do {
System.out.println("Found time: " + m.group());
} while (m.find());
Output running both:
Has time
Found time: 6:00 PM
Found time: 14:00