Regex not working

Hello, I would like to represent the following date format in regex but it is failing with the following error.
What is the proper regex that I need to specify in the script? Thanks. Below is the part of the script that I am using.

String time = Mobile.getText(findTestObject(‘Object Repository/Camera Page/Playback Date and Time (Version 121)’),10) //This takes a bit of time (because text keeps changing?)
int max = 3 //Do it max 3 times
int current = 0 //Set current to 0
while(time.equals("") && current < max) //If time is empty (didn’t load in time)
{
sleep(5000) //To give enough time for it to appear
time = Mobile.getText(findTestObject(‘Object Repository/Camera Page/Playback Date and Time (Version 121)’),10) //This takes a bit of time (because text keeps changing?)
current++
}
Mobile.comment("—Verify time string obeys regex (Month ##, Year HH:MM:SS (AM|PM) Timezone)—")
Mobile.verifyMatch(time, “[A-Za-z]{3} [0-9]{1,2}, [0-9]{4} [0-5]{0,1}[0-9]:[0-5]{0,1}[0-9]:[0-5]{0,1}[0-9] (AM |PM )?((?!UTC)[A-Za-z]{1,6}|UTC((-|\+)[0-9]{2})?)”,true)

04-28-2021 04:31:44 PM verifyMatch(time, “[A-Za-z]{3} [0-9]{1,2}, [0-9]{4} [0-5]{0,1}[0-9]:[0-5]{0,1}[0-9]:[0-5]{0,1}[0-9] (AM |PM )?((?!UTC)[A-Za-z]{1,6}|UTC((-|+)[0-9]{2})?)”, true)

Elapsed time: 0.056s

Unable to verify match between actual text ‘Apr. 28, 2021 16:29:55 GMT’ and expected text ‘[A-Za-z]{3} [0-9]{1,2}, [0-9]{4} [0-5]{0,1}[0-9]:[0-5]{0,1}[0-9]:[0-5]{0,1}[0-9] (AM |PM )?((?!UTC)[A-Za-z]{1,6}|UTC((-|+)[0-9]{2})?)’ using regular expression (Root cause: com.kms.katalon.core.exception.StepFailedException: Actual text ‘Apr. 28, 2021 16:29:55 GMT’ and expected text ‘[A-Za-z]{3} [0-9]{1,2}, [0-9]{4} [0-5]{0,1}[0-9]:[0-5]{0,1}[0-9]:[0-5]{0,1}[0-9] (AM |PM )?((?!UTC)[A-Za-z]{1,6}|UTC((-|+)[0-9]{2})?)’ are not matched using regular expression
at com.kms.katalon.core.keyword.builtin.VerifyMatchKeyword$_verifyMatch_closure1.doCall(VerifyMatchKeyword.groovy:57)
at com.kms.katalon.core.keyword.builtin.VerifyMatchKeyword$_verifyMatch_closure1.call(VerifyMatchKeyword.groovy)
at com.kms.katalon.core.keyword.internal.KeywordMain.runKeyword(KeywordMain.groovy:68)
at com.kms.katalon.core.keyword.builtin.VerifyMatchKeyword.verifyMatch(VerifyMatchKeyword.groovy:60)
at com.kms.katalon.core.keyword.builtin.VerifyMatchKeyword.execute(VerifyMatchKeyword.groovy:45)
at com.kms.katalon.core.keyword.internal.KeywordExecutor.executeKeywordForPlatform(KeywordExecutor.groovy:73)
at com.kms.katalon.core.keyword.BuiltinKeywords.verifyMatch(BuiltinKeywords.groovy:73)
at New Test Case.run(New Test Case:69)
at com.kms.katalon.core.main.ScriptEngine.run(ScriptEngine.java:194)
at com.kms.katalon.core.main.ScriptEngine.runScriptAsRawText(ScriptEngine.java:119)
at com.kms.katalon.core.main.TestCaseExecutor.runScript(TestCaseExecutor.java:398)
at com.kms.katalon.core.main.TestCaseExecutor.doExecute(TestCaseExecutor.java:389)
at com.kms.katalon.core.main.TestCaseExecutor.processExecutionPhase(TestCaseExecutor.java:368)
at com.kms.katalon.core.main.TestCaseExecutor.accessMainPhase(TestCaseExecutor.java:360)
at com.kms.katalon.core.main.TestCaseExecutor.execute(TestCaseExecutor.java:255)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:114)
at com.kms.katalon.core.main.TestCaseMain.runTestCase(TestCaseMain.java:105)
at com.kms.katalon.core.main.TestCaseMain$runTestCase$0.call(Unknown Source)
at TempTestCase1619641697063.run(TempTestCase1619641697063.groovy:25)
)

I usually use \\d format for the hour, minute and seconds and \\s for space between the different parts, like \\s\\d{1,2}:\\d{2}:\\d{2}\\s(A|P)M.

Use the link below to test your RegEx until you get a match:

I have tried and cannot get a match, is there a way to generate a regular expression from a date?
Eg: Apr. 28, 2021 15:37:32 GMT

Personally, I create a Date object in the String format that I want and then append the time portion as I showed you above to verify a time-date stamp.

Date todaysDate = new Date();
GlobalVariable.gFormattedDate = todaysDate.format("MM/dd/yyyy");
GlobalVariable.gFormattedYesterdayDate = todaysDate.plus(-1).format("MM/dd/yyyy");

def yourDate = todaysDate.format("MMM d, yyyy");

Your time-stamp is more complicated but maybe someone has done it before.

Sample code

I have made a sample code:

import java.time.LocalDateTime
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
import java.util.regex.Matcher
import java.util.regex.Pattern

import com.kms.katalon.core.util.KeywordUtil

String datetimeString = "Apr. 28, 2021 16:29:55 GMT"

// parse the string with Regex
Pattern p = Pattern.compile("([A-Za-z]{3})\\. ([0-9]{1,2}), ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([A-Z]{3})")
Matcher m = p.matcher(datetimeString)
if (m.find()) {
	println "Month=${m.group(1)} Day=${m.group(2)} Year=${m.group(3)} Hours=${m.group(4)} Minutes=${m.group(5)} Seconds=${m.group(6)} Zone=${m.group(7)}"
} else {
	throw new IllegalStateException("'${datetimeString}' does not match regex '${p.toString()}'")
}

// converting String to ZonedDateTime
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM. dd, yyyy HH:mm:ss z").withLocale(Locale.ENGLISH)
ZonedDateTime zonedDateTime = ZonedDateTime.parse(datetimeString, formatter)
println zonedDateTime

// verify if the given datetime is in between [now: 1week ago]
LocalDateTime now = LocalDateTime.now()
LocalDateTime oneWeekAgo = now.minusDays(7)
LocalDateTime givenDT = zonedDateTime.toLocalDateTime()
if (now.compareTo(givenDT) >= 0 && givenDT.compareTo(oneWeekAgo) > 0) {
	println "the given datetime ${givenDT} is in between now (${now}) and 1 week ago (${oneWeekAgo})"
} else {
	KeywordUtil.markFailedAndStop("the given datetime ${givenDT} is NOT in between now (${now}) and 1 week ago (${oneWeekAgo})")
}

When the above Test Case is executed, the following message comes up in the console

...
Month=Apr Day=28 Year=2021 Hours=16 Minutes=29 Seconds=55 Zone=GMT
...
the given datetime 2021-04-28T16:29:55 is in between now (2021-04-29T13:46:01.542) and 1 week ago (2021-04-22T13:46:01.542)

Description

Your regular expression

  • [A-Za-z]{3} [0-9]{1,2}, [0-9]{4} [0-5]{0,1}[0-9]:[0-5]{0,1}[0-9]:[0-5]{0,1}[0-9] (AM |PM )?((?!UTC)[A-Za-z]{1,6}|UTC((-|+)[0-9]{2})?)

has several problems.

  1. The given string starts with “Apr.”, which has a dot(.). Your regex ignores the dot. Therefore your regex fails to match.
  2. Your regex is unnecessary complex; it has redundant parts (“AM”, “PM”, “UTC”). A simpler regex would suffice to parse the given string into string components.

If you want to perform any date-time calculation, it is not enough to parse a given string into string components with regex.

You should parse a given string with java.time.DateTimeFormetter to convert to java.time.LocalDateTime or java.time.ZoneDateTime object. The classes in the java.time package enable you to perform various calculations over date-time data out of box. See the above snippet as example.

There are a few useful tutorials on the “java.time” package:

1 Like

Thanks for the sample code. I just want to verify that the date/time shown on the mobile app matches the regex expression.

So i was able to get the match with the following line.

Mobile.verifyMatch(time,"([A-Za-z]{3})\. ([0-9]{1,2}), ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([A-Z]{3})",true)

Question is, since only May has no dot, and the other months have a dot (eg: Apr. , how would you represent that?

You can enumerate the names of months, some have a dot, some have not.

"(Jan\.|Feb\.|Mar\.|Apr\.|May|Jun\.|Jul\.|Aug\.|Sep\.|Oct\.|Nov\.|Dec\.) ([0-9]{1,2}), ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([A-Z]{3})"

Alternatively:

"([A-Za-z]{3}\.?) ([0-9]{1,2}), ([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2}) ([A-Z]{3})"