Need a Regular Expression for the validation of Time format - javascript

I have a datetime textbox which contains both date and time .
I want to validate the time.For the date i have validated.
e.g datetime value is 04/23/2013 05:26 pm;
I need a regex which can validate the time that will be in format 00:00:00 .
all are digits and no special character or other than digits will be entered.
i want only to validate dd:dd:dd all are 2 digits.
I can enter for example 10:10:10 and 01:02.
i have tried with js way like this.i have no knowledge in regex.so i want suggestions.
function ValidateDate()
{
//getting the value from textbox
var dateVal=document.getElementById('txtDateTime').value;
//after one space there is time..as i am using a datepicker and timepicker format
var time=dateVal.split(' ')[1];
var isValidTime=CheckTime(time);
}
function CheckTime(time)
{
var timePart=time.split(":");
var hour = timePart[0];
var minute = timePart[1];
var second = timePart[2];
if((parseInt(hour,10)<0) || (parseInt(hour,10)>59))
{
return false;
}
if((parseInt(minute)>59) || (parseInt(minute)<0))
{
return false;
}
if((parseInt(second)<0) || (parseInt(second)>59))
{
return false;
}
return true;
}
Thanks for your suggestions.

A simple regex of /^([0-1][0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9]))?$/g will work.
10:00:00 - OK
01:00:00 - OK
60:00:00 - Fail
30 - Fail
30:00 - Fail
23:59 - OK
24:00 - Fail
23:60:60 - Fail
23:59:59 - OK
Regex autopsy:
^ - This is where the sentence MUST start
([0-1][0-9]|2[0-3])
[0-1][0-9] - The digits 0 to 1 followed by any digit between 0 and 9
| - OR
2[0-3] - The digit 2 followed by any digit between 0 and 3
: - A literal : character
([0-5][0-9]) - The digits from 0 to 5 followed by any digit between 0 and 9
(?::([0-5][0-9]))?
?: - a non capturing group
: - A literal : character
([0-5][0-9]) - The digits from 0 to 5 followed by any digit between 0 and 9
? - means that the previous statement should be there 0 or 1 time (so it doesn't have to be there).
$ - This is where the sentence MUST end

The following regex should work: /^\d{2}:\d{2}(?::\d{2})?$/.

Related

How to format number in JavaScript

I need to do dynamic validation on a number while user giving input. Number format should be-- before decimal it should restrict 12 digit and after decimal 2 digit.
I have written one validation function using Onkeyup and by giving maxlength. But I am facing issue like, if I remove one digit after decimal then its allowing more than 13 digit before decimal.
below function I have written for validation
function validation(e){
var t = e.value;
if( t.indexOf(".") <= 0 ) {
e.value = t.substr(0,12);
}
if( ( t.slice( 0, e.selectionStart ).length >= ( t.indexOf(".") + 3 ) ) {
e.value = ( t.indexOf(".") >= 0 ) ?
( t.substr( 0, t.indexOf(".") ) + t.substr( t.indexOf("."), 3 ) ) :
t
}
Appreciate any help!!
Thanks.
Regex
You can use a regular expression (regex).
For instance:
^(([1-9]{1}[0-9]{0,11}|[0-9]{1}))(\.\d{1,2})?$
Ok let's check out:
Numbers before the decimal point: ([1-9]{1}[0-9]{0,11}|[0-9]{1})
So either [1-9]{1}[0-9]{0,11} or [0-9]{1}, where the first expression prevents leading zeros and second expression makes the input o f 0 possible.
These expressions are followed by an optional decimal point (\.\d{1,2})?. The ? means that the expression can be there 0 or 1 times (so the input can be a decimal number or not). After the decimal point there have to be one 1 or 2 numbers (decimals).
You can try the expressions here: Online regex tester and debugger.
This should work:
123456789123
123.40
0
0.0
953
953.1
953.0
953.01
953.12
This should not work:
1234567891239 // 13 numbers
000.12 // leading zeros
123.001 // Too many decimals
Implementation
Possibility 1 is to insert the regex directly into the <input> using the pattern attribute. Possibility 2 is to do the validation via javascript. Note that you have to escape the backslashes \\.
let pattern = '^(([1-9]{1}[0-9]{0,11}|[0-9]{1}))(\\.\\d{1,2})?$';
let regex = new Regex(pattern);
function validation(e){
if(regex.test(e.value)){
// Value fits the pattern
}else{
// Value do not fit the pattern
}
}

JavaScript regex two string number separated by ( : ) individual max min calculation

I need to validate JavaScript string like "03:39" with Regex. Rules are following,
1.First part of the string which is before (:) is allowed from 0 to 24
2.Second part of the string which is after (:) is allowed from 0 to 59
3.Single digit number of both part can either be start with 0 like 01 or 02 or with out 0 like 1 , 2.
Now i have wrote a JavaScript regex code which is following.
var dateRegEx = /^n(0[0-2][0-4]|[0-24])(:)(0|[0-5][0-9]|[0-59])$/;
if ($(element).val().match(dateRegEx) === null) {
// my rest of the code
}
now, when user insert 0:38, 01:38 or 02:59 it get validated but when the first part incensed after 2 like 03:38 it not validating the string.
So what am i doing wrong ??
For hours, your current 0[0-2][0-4] requires three digits (none of which can be above 4), whereas [0-24] will only match one digit (a 0, 1, 2, or 4).
Rather, to match hours (00 to 24), you should use (?:2[0-4]|[01]?[0-9]); either a 2 followed by a number from 0 to 4, or an (optional) 0 or 1 followed by any other digit.
To match minutes (00 to 59), use [0-5]?[0-9] - an optional digit from 0 to 5, followed by a digit from 0 to 9.
^(?:2[0-4]|[01]?[0-9]):[0-5]?[0-9]$
https://regex101.com/r/0QxX7w/1
Note that if you're just matching a single character like :, don't put it in a character set. Also, because you don't want an n at the beginning of the match, remove it from the beginning of your pattern.
Well i think you don't need regex here you can do directly like this
function check(input){
let temp = input.split(':')
return (0 <= temp[0] && temp[0] <=24 ) && ( 0<= temp[1] && temp[1] <=59)
}
console.log(check('03:380'))
console.log(check('03:38'))
console.log(check('30:0'))
With regex you can do it like this
function check(input){
return /^(?:[01]?[0-9]|[0-2][0-4]):[0-5]?[0-9]$/.test(input)
}
console.log(check('03:30'))
console.log(check('03:380'))
console.log(check('33:30'))
console.log(check('24:59'))
console.log(check('03:60'))
console.log(check('0:0'))
console.log(check('0:30'))

time limit on regular expression in format MM:SS:HH

I need to validate a user input for minutes, seconds, and hundredths in the format MM:SS:HH. However, user's input can not go over 10 minutes. I'm not sure how to limit that and still keep for example 01:01:01 valid.
/^[0-1][0-0]:[0-5][0-9]:[0-9][0-9]$/
This is the expression I had, but my example of 01:01:01 would not have worked.
Brief
I would definitely split the time string on : and then test each part. That's the simplest solution. Alternatively, you can do this relatively easily using regex.
Code
Method 1 - No regex
const str = ["00:00:00", "05:05:05", "10:00:00", "10:00:01", "10:59:59", "20:20:20"];
str.forEach(function(s) {
var a = s.split(":").map(Number);
if(a[0] < 10 || (a[0] === 10 && a[1] === 0 && a[2] === 0)) {
console.log(`Valid: ${s}`);
} else {
console.log(`Invalid: ${s}`);
}
});
Method 2 - Regex
const regex = /^(?:0\d(?::[0-5]\d){2}|10:00:00)$/;
const str = ["00:00:00", "05:05:05", "10:00:00", "10:00:01", "10:59:59", "20:20:20"];
str.forEach(function(s) {
if(regex.exec(s) !== null) {
console.log(`Valid: ${s}`);
} else {
console.log(`Invalid: ${s}`);
}
});
Explanation
I'll only explain the regex in Method 2 as the rest is fairly simple. If you need an explanation about any other parts, however, feel free to ask!
^ Assert position at the start of the line
(?:0\d(?::[0-5]\d){2}|10:00:00) Match either of the following
0\d(?::[0-5]\d){2} Match the following
0 Match this literally
\d Match any digit
(?::[0-5]\d){2} Match the following exactly twice
: Match this literally
[0-5] Match a number in the range between 0 and 5
\d Match any digit
10:00:00 Match this literally
$ Assert position at the end of the line
/(10:00:00|^0[0-9]:[0-5][0-9]:[0-5][0-9]$)/
['10:00:01', '10:00:00', '09:59:59', '05:05:05']
.forEach(t => console.log(t.match(/(10:00:00|^0[0-9]:[0-5][0-9]:[0-5][0-9]$)/)))
Your regex is close. Simply change your regex to:
/^(10:00:00|0[0-9]:[0-5][0-9]:[0-9][0-9])$/

JavaScript RegExp to automatically format Pattern

I have seen a lot of functions that format telephone or number (comma and decimals) in stackflow community like this question here and others. Here's what I want to:
Step 1: Maintain a Library for patterns like this:
var library = {
fullDate : {
pattern : /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/,
error : "Invalid Date format. Use YYYY-MM-DD format."
},
fullDateTime : {
pattern : /^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}$/,
error : "Invalid DateTime format. Use YYYY-MM-DD HH:MM (24-hour) format."
},
tel : {
pattern : /^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/,
error : "Invalid Telephone format."
}
};
Step 2: Automatically add a character as they type. For exapmple, add a - after 4 numbers in Date.
I have a text field say:
<input type="text" data-validate="fullDate" placeholder="YYYY-MM-DD"/>
And possible place to start script as:
$('body').on('keyup','input',function(){
var validate = $(this).data('validate');
var pattern = library[validate].pattern;
//Some more steps here....
});
But, I cannot make any further because I am new to RegExp. Here's a startup fiddle. Anyone?
Further Notes: I have been able to validate using the following functions but what I want to is automatically make pattern:
function validate(libraryItem, subject){
var item = library[libraryItem];
if(item !== undefined){
var pattern = item.pattern;
if(validatePattern(pattern, subject)){
return true;
} else {
return item.error;
}
}
return false;
}
function validatePattern(pattern, subject){
return pattern.test(subject);
}
It is not as complicated as you think. What you are looking for is JQuery Masked input and other alternative libraries. Here is the documentation. All you need is:
<input id="date" type="text" placeholder="YYYY-MM-DD"/>
and the script:
$("#date").mask("9999-99-99",{placeholder:"YYYY-MM-DD"});
Here is demo pen link:
http://codepen.io/anon/pen/gpRyBp
To implement validation use this library:
https://github.com/RobinHerbots/jquery.inputmask
What needed here is breaking up the regular expression in sub expression which matches part of the string and suggest completion based upon next character in the Regular Expression.
I wrote a naive Parser which parses the expression and divides into atomic subexpression.
var parser = function(input) {
var tokenStack = [];
var suggestions = [];
var suggestion;
var lookAhead;
if (input[0] === '/')
input = input.slice(1, input.length - 1);
var i;
for (i = 0; i < input.length - 1; i++) {
lookAhead = input[i + 1];
switch (input[i]) {
case '(':
tokenStack.push('(');
break;
case '[':
tokenStack.push('[');
break;
case ')':
if (tokenStack[tokenStack.length - 1] === '(') {
tokenStack.pop();
if (tokenStack.length === 0) {
suggestion = generateSuggestion(input, i);
if (suggestion !== null)
suggestions.push(suggestion);
}
}
else
throw 'bracket mismatch';
break;
case ']':
if (lookAhead === '{') {
while (input[i] !== '}')
i++;
}
if (tokenStack[tokenStack.length - 1] === '[') {
tokenStack.pop();
if (tokenStack.length === 0) {
suggestion = generateSuggestion(input, i);
if (suggestion !== null)
suggestions.push(suggestion);
}
}
else
throw 'bracket mismatch';
break;
default:
if (tokenStack.length === 0) {
suggestion = generateSuggestion(input, i);
if (suggestion !== null)
suggestions.push(suggestion);
}
break;
}
}
return suggestions;
}
var generateSuggestion = function(input, index) {
if (input[index].match(/[a-zA-Z\-\ \.:]/) !== null)
return {
'regex': input.slice(0, index) + '$',
'suggestion': input[index]
};
else
return null;
}
Here is sample input and output of parser()
parser('/^[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}$/');
// output:
[ { regex: '^[0-9]{4}$', suggestion: '-' },
{ regex: '^[0-9]{4}-[0-9]{1,2}$', suggestion: '-' } ]
Thus on every keyup you need to check the list of RegExp generated by parser and if any of it matches the input then use the suggestion.
EDIT:
Edited generateSuggestion to match only full expression.
Here is sample fiddle: http://jsfiddle.net/a7kkL6xu/6/
With backspace ignored: http://jsfiddle.net/a7kkL6xu/7/
This could be done with a single regex.
This requires a MM:DD and HH:MM to be 2 digits and YYYY to be 4 digits on a
fully valid entry, but matches all the partials.
It could be made to allow a single digit validity for the 2 digit valid mentioned.
But doing so, will make premature suggestions on the - - [ ] : form.
If you want to not inject the suggestion, then 1 or 2 digits is fine.
JavaScript doesn't allow lookbehind assertions, so partial field expressions
are below the valid field expressions in their respective groups.
Basically what happens is the input is rewritten on each key press event.
All you do is match the current input within the event handler.
Without suggestions, you just write over the input with the entire match (group 0).
The match (group 0) will only contain a valid partial or full match.
The valid completed field capture groups are 1 through 5
[ Year, Month, Day, Hours, Minutes ]
The incomplete field captures are groups 6 through 10
[ Minutes, Hours, Day, Month, Year ]
This is the logic:
// Note 1 - can handle control chars by just returning.
// Note 2 - can avoid rewrite by keeping a global of last good,
// then return if current == last.
if ( last char of group 0 is a dash '-' or space ' ' or colon ':'
or any of groups 6 - 10 matched
or group 5 matched )
set input equal to the group 0 string;
else if ( group 4 matched ) // Hours
set input equal to group 0 string + ':';
else if ( group 3 matched ) // Day
set input equal to group 0 string + ' ';
else if ( group 1 or 2 matched ) // Year or Month
set input equal to group 0 string + '-';
else // Here, effectively strips bad chars from input box
// before they are displayed.
set input equal to group 0 string;
Note that if a group didn't match it's value will be NULL
and to check the entire validity, there should be no partials and
groups 1 - 3 must be complete for just YYYY-MM-DD or 1 - 5 with the optional
time HH:MM
Final Note: This is a parser, and effectively a test case of the look and feel, ie. flicker, of real time input rewrite.
If it goes well, the logic in the handler can include Day validation (and rewrite) based on the month.
Also, the premise can be expanded to any type of input, any type of form and
form delimiter combinations, etc..
If it works, you can build a library.
# /^(?:(19\d{2}|20[0-1]\d|202[0-5])(?:-(?:(0[1-9]|1[0-2])(?:-(?:(0[1-9]|[1-2]\d|3[0-1])(?:[ ](?:(0\d|1\d|2[0-3])(?::(?:(0\d|[1-5][0-9])|([0-5]))?)?|([0-2]))?)?|([0-3]))?)?|([01]))?)?|(19\d?|20[0-2]?|[12]))/
^ # BOL
(?:
( # (1 start), Year 1900 - 2025
19 \d{2}
| 20 [0-1] \d
| 202 [0-5]
) # (1 end)
(?:
- # -
(?:
( # (2 start), Month 00 - 12
0 [1-9]
| 1 [0-2]
) # (2 end)
(?:
- # -
(?:
( # (3 start), Day 00 - 31
0 [1-9]
| [1-2] \d
| 3 [0-1]
) # (3 end)
(?:
[ ] # space
(?:
( # (4 start), Hour 00 - 23
0 \d
| 1 \d
| 2 [0-3]
) # (4 end)
(?:
: # :
(?:
( # (5 start), Minutes 00 - 59
0 \d
| [1-5] [0-9]
) # (5 end)
|
( [0-5] ) # (6)
)?
)?
|
( [0-2] ) # (7)
)?
)?
|
( [0-3] ) # (8)
)?
)?
|
( [01] ) # (9)
)?
)?
|
( # (10 start)
19 \d?
|
20 [0-2]?
|
[12]
) # (10 end)
)
It is only possible to add a character if it is the single possible choice at this point. An example would be a regex for the YYYY-MM-DD HH24:mm format: the -, the : and the (space) could be added. Here is the corresponding regex (/ ommitted to make it more readable, it is stricter than the one in the question, some illegal dates are still possible like 31st of February):
^[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01]) (?:[01][0-9]|2[0-3]):[0-5][0-9]$
For fixed length inputs you could use #DineshDevkota's solution to add the literals and verify the whole text with regex. I think it's the cleanest and simplest solution. You could also capture the year, month and day to verify the day mathematically. Also rules like "date not in the future" or "max. 100 years in past" can only be veryfied in JS and not with just regex.
The only additional patterns that come to mind where a character could be automatically added:
A + after a literal, e.g. on A+ add an A
Minimal occurances in general, e.g. on (?:foo){2,5} add foofoo not to be confused with [fo]{2,5} where no characters can be added
Literals after the max length of a variable part, e.g. on (?:foo){1,3}bar add bar after the text is foofoofoo before it is not possible.
Add remainders e.g. foo|bar add ar when b was typed and oo when f was typed (also possible in the pattern shown in 3.) but this won't work for ^[a-z]+?(?:foo|bar)$ because we don't know when the user plans on ending the text and it can get really complicated (foo|flo|flu|food|fish only sh can be added after fi).
As seen in 3. and 4. those additional cases where characters could be added are of very limited use as soon as there are parts with variable length. You would have to parse the regex, split it in literal and regex parts. Then you have to parse/analyse the regex parts to incorporate the additional cases mentioned above where characters could be added. Really not worth the trouble if you ask me. (Not a single character can be added in your tel pattern.)

Year of date validation is failing

I need to do a date validation to accept it in dd/mm/yyyy format. However all conditions are working fine except that if I enter year of 6 digits it is also accepting it, like -
12/12/200000
as per my code is valid. Below is my code:
function validate(value) {
if(!value.match(/\d\d\/\d\d\/\d\d\d\d/))
return false;
return checkdate(value);
}
function checkdate(val)
{
var dates = val.split(/\D/);
if(dates[0] <= 0 || dates[0] > 31)
return false;
if(dates[1] <= 0 || dates[1] > 12)
return false;
var now = new Date(dates[2],dates[1]-1,dates[0]);
if (isNaN(now))
return false;
now.setHours(0,0,0,0);
if (now.getFullYear() == dates[2] && now.getMonth() + 1 == dates[1] && now.getDate() == dates[0])
return true;
return false;
}
I am not sure why it allowing year as 6 digits valid input?
The problem is in validate function, regular expression it matches against allows input values you don't want to pass as valid. Besides obvious dd/mm/yyyy format, it allows found text to be anywhere in string. Basically, you said for it to check "if there's said expression inside string", when it should have been "if the whole string matches this expression".
To fix the issue, add ^ at the beginning and $ at the end. ^ stands for string start and $ for string end:
/^\d\d\/\d\d\/\d\d\d\d$/
I think you would benefit from reading documentation on regular expression syntax used by JavaScript.
While at at, humans tend to have issues reading long repeating sequences of similar characters, like in your regexp. This expression is easer to understand and does exactly the same thing:
/^\d{2}\/\d{2}\/\d{4}$/
You're not limiting the regex with start and stop delimiters, so 12/12/200000 is a match as it matched the regex, and then some
if (!value.match(/^\d\d\/\d\d\/\d\d\d\d$/) )
As a sidenote, you don't have to type \d four times, you can do \d{4} to match four instances of \d
If you want to validate a date string by creating a Date object, you don't need to check the entire pattern, just create and Date and check the result. Do you really need two digits for day and month number?
If you want a 4 digit year, that must be checked separately as the constructor will happily convert two digit years to 20th century. If you really need two digit day and month, that can be checked at the same time as the year:
function validateDMY(s) {
var b = s.split(/\D/);
var d = new Date(b[2], --b[1], b[0]);
return d && /^\d{4}$/.test(b[2]) && b[1] == d.getMonth();
}
console.log(validateDMY('30/02/2015')); // false
console.log(validateDMY('30/22/2015')); // false
console.log(validateDMY('02/02/15')); // false
console.log(validateDMY('30/01/2015')); // true

Categories

Resources