Year of date validation is failing - javascript

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

Related

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])$/

What would the regular expression for this situation be?

I'm pretty new to JavaScript, and I've been trying to figure out the regular expression for this for a while.
I need to validate a user entry in the form of "mm/yy".
The 1st digit of the month must be 0 or 1. If it is 0 then the 2nd digit can be from 1 to 9. If it is 1, then the second digit can be 0 to 2. The year can be 14 to 19. It must have the slash.
This is what I have so far:
var reExp = /^0(?=\d)|1(?=1)|2\/14$/; //RegExp for expiry
if ($('expiry').value.search(reExp)==-1){
$('expiry').value = '';
$('expiryMsg').style.fontSize="10px";
$('expiryMsg').innerHTML = "Invalid Entry: Must be a valid expiry date.";
}
else {
$('expiryMsg').innerHTML = "*";
$('expiryMsg').style.fontSize="16px";
}
I want to do all the validation in one expression, is this possible?
Thanks!
You can use this pattern:
/^(?:0[1-9]|1[0-2])\/1[4-9]$/

Need a Regular Expression for the validation of Time format

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})?$/.

parseInt() returning incorrect value; DOB validation

Wondering if anyone could shed some light as I’m pulling my hair out over this one!
I have written a simple function to validate a users Date of birth which is all well and good, or at least it was until I realised it wasn't working as expected!
The function, as below, takes 2 parameters, dobNum (the value of an input field) and dmy (a switch variable that receives either ‘dd’, ‘mm’ or ‘yyyy’). The function is called as follows with the value of an input field so there shouldn’t be any object based problems:
onblur=”validateDOB(this.value, ‘mm’);
I have spent ages trying to get to the bottom of this and there seems to be a problem with the parseInt() statement.
This works fine for the days and months until you pass either a 08 (zero, eight) or a 09 (zero,nine). Here the result of the parseInt() returns as 0 rather than an 8 or 9 respectively.
But this is only a problem with 08 and 09, passing numbers 01 to 07 returns 1 to 7 as expected.
Similarly, when passing single digits, 1 to 9, to the function, parseInt() returns the appropriate value as an integer.
Really struggling to fathom this one out. Conversely removing the parseInt statement completely seems to work however this leaves the dobNum value as a string which I don’t feel is particularly good practice.
Can anyone shed some light on this please? (this problem occurs in both firefox and IE)
Many thanks,
SMc
var DOBddOK = false;
var DOBmmOK = false;
var DOByyyyOK = false;
function validateDOB (dobNum, dmy) {
// Set Regexp based on dmy var.
if (dmy.length == 2) var reg = /^([0-9]{1,2})$/;
else var reg = /^([0-9]{4})$/;
var numOK = reg.test(dobNum);
alert("NumOK: "+numOK); //test
// If dobNum value passes regExp test then convert it to an integer
if (numOK) {
var numVar = parseInt(dobNum);
//var numVar = dobNum;
alert("NumVar: "+numVar); //test
}
alert("dmy: "+dmy); //test
switch (dmy) {
case "dd":
if (numOK && numVar <= 31 && numVar > 0) DOBddOK = true;
else DOBddOK = false;
break;
case "mm":
if (numOK && numVar <= 12 && numVar > 0) DOBmmOK = true;
else DOBmmOK = false;
break;
case "yyyy":
var d = new Date();
d = d.getFullYear();
if (numOK && numVar <= (d-18) && numVar >= (d-80)) DOByyyyOK = true;
else DOByyyyOK = false;
break;
}
}
When the parseInt function finds a leading zero in the passed string, it will implicitly parse the number as octal.
It is always recommended to use the radix argument:
parseInt('08', 10); // 8
parseInt('09', 10); // 9
This have caused so many problems over the time that in the new version of the language standard, ECMAScript 5, the implicit octal detection has been removed from the parseInt algorithm. But ES5 is not completely supported yet.
There are other ways to convert a String to Number in JavaScript that do not present this problem, for example:
The unary plus operator:
+'08'; // 8
The Number constructor called as a Function:
Number('08'); // 8
In my opinion parseInt and the later two ways I've described have a (subtly) different semantic meaning.
The former is clearly parsing, for example:
parseInt('12px'); // 12
parseInt('10yo'); // 10
parseInt('1111', 2); // 15
And the last two ways are for doing String to Number type conversion.
It's treating strings with a leading zero as octal, you can specify a second parameter giving the radix as 10.
See link text
Try to use the radix parseInt(dobNum, 10) to parse your integer in base 10

javascript regexp, validating date problem

I have some code for validating date below:
function validateForm() {
var errFound = 0;
//var patt_date = new RegExp("^((((19|20)(([02468][048])|([13579][26]))-02-29))|((20[0-9][0-9])|(19[0-9][0-9]))-((((0[1-9])|(1[0-2]))-((0[1-9])|(1\d)|(2[0-8])))|((((0[13578])|(1[02]))-31)|(((0[1,3-9])|(1[0-2]))-(29|30)))))$");
var patt_date = new RegExp("^[0-9]{4}-(((0[13578]|(10|12))-(0[1-9]|[1-2][0-9]|3[0-1]))|(02-(0[1-9]|[1-2][0-9]))|((0[469]|11)-(0[1-9]|[1-2][0-9]|30)))$");
if (patt_date.test(document.getElementById("datefrom").value) == false){errFound = errFound + 1;document.getElementById("datefrom").className = "error";}
if (errFound > 0)
alert('Please correct red colored field!');
else
return true;
return false;
}
Above code should work with YYYY-MM-DD format, but fail to validate date such as "2009-02-29"
The commented code should work (//var patt_date = new RegExp...), it can catch "2009-02-29", but it ruin the validation when i put invalid data and try to correct it, it keeps complain there something wrong with form value after i had correct them (especially on form with multiple input)
Maybe someone can fix the current regex?
Edited, what i want just a simple replacement for above regexp, mean a new regexp pattern not the whole new method to validate date
And for reference, i simply grab the regexp pattern from:
http://www.regexlib.com/REDetails.aspx?regexp_id=694 and
http://www.regexlib.com/REDetails.aspx?regexp_id=933
Tested with 2009-02-29, 1st link work & 2nd not. Again the problem was only the 2nd regexp didn't detect value 2009-02-29 as invalid while 1st can (but it ruin my code? so it's must be there something wrong with it).
Thanks,
Dels
Don't do the whole date validation with a regular expression, that's really pushing the limits of what regexps were designed for. I would suggest this procedure instead:
Check date against regexp /^\d{4}-\d{2}-\d{2}$/
Extract year, month, and day using substr() and convert to integers
Use some if statements to validate the integers. Like so:
if (month == 2) {
if (day == 29) {
if (year % 4 != 0 || year % 100 == 0 && year % 400 != 0) {
// fail
}
}
else if (day > 28) {
// fail
}
}
else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day > 30) {
// fail
}
}
else {
if (day > 31) {
// fail
}
(That could certainly be written more concisely) Alternatively, you could probably perform this validation using Javascript's Date class - you might have to do something like parsing the date, converting it back to a string, and checking if the two strings are equal. (I'm not a Javascript expert)
I kinda agree with David on this... Regex matches should not be used as an exclusive criterion to decide if the passed date is, in fact, valid. The usual procedure in Javascript validation involves a few steps :
a. The first step is to ensure that the passed string matches expected date formats by matching it against a Regex. The following may be a stricter Regex pattern.
// Assuming that the only allowed separator is a forward slash.
// Expected format: yyyy-mm-dd
/^[12][90][\d][\d]-[0-3]?[\d]-[01]?[\d]$/
b. The second step is to parse the string into a Date object which returns the no. of milliseconds since 1970. Use this number as a parameter for the Date constructor.
c. Since JS automatically rolls over the passed date to the nearest valid value, you still cannot be certain if the Date object created matches that which was passed. To determine if this happened, the best way is to split the passed string according to the separator and compare individual date components:
// d is the created Date object as explained above.
var arrDateParts = inputDate.split("-");
if ((d.getFullYear() == arrDateParts[0]) && (d.getMonth() == arrDateParts[1]) && (d.getDate() == arrDateParts[2]))
return true;
else
return false;
This javascript code validates date exactly. You can copy it and test it in your browser.
var regDate = '^(19[0-9]{2}|2[0-9]{3})-(0[1-9]{1}|1[0-2]{1}){1}-(0[1-9]|(1|2)[0-9]|3[0-1]){1}$';
var txt='2010-01-31';
if(txt.match(regDate))
{
alert('date match');
}

Categories

Resources