Javascript regex help - javascript

Does anybody know how I can make the forwardslash and format: dd/mm/yyyy compulsory in this regex?
// Checks a string to see if it in a valid date format
// of (D)D/(M)M/(YY)YY and returns true/false
function isValidDate(s) {
// format D(D)/M(M)/(YY)YY
var dateFormat = /^\d{1,4}[\.|\/|-]\d{1,2}[\.|\/|-]\d{1,4}$/;
if (dateFormat.test(s)) {
// remove any leading zeros from date values
s = s.replace(/0*(\d*)/gi,"$1");
var dateArray = s.split(/[\.|\/|-]/);
// correct month value
dateArray[1] = dateArray[1]-1;
// correct year value
if (dateArray[2].length<4) {
// correct year value
dateArray[2] = (parseInt(dateArray[2]) < 50) ? 2000 + parseInt(dateArray[2]) : 1900 + parseInt(dateArray[2]);
}
var testDate = new Date(dateArray[2], dateArray[1], dateArray[0]);
if (testDate.getDate()!=dateArray[0] || testDate.getMonth()!=dateArray[1] || testDate.getFullYear()!=dateArray[2]) {
return false;
} else {
return true;
}
} else {
return false;
}
}

for mandatory dd/mm/yyyy try:
var dateFormat = /^\d{2}\/\d{2}\/\d{4}$/;
I didn't look to closely at the rest of the function, but I think that is what you were going for.

this would do it i think..
/^\d{2}\/\d{2}\/\d{4}$/
forced 2 digit days, 2 digit months, 4 digit years and / as seperator..
or
/^[0-3][0-9]\/[0-1][0-9]\/\d{4}$/
to enforce a little bounds control..
day: 00-39
month: 00-19

Related

Date validation and relative delta between two dates in javascript

I have an interface where I receive a date in this format: Month/Year, ex: 11/2022.
I would like to verify that this is a valid date.
I use the datatables editor. The configuration (see below) of the field works well, but since the user can enter the date himself without going through the calendar, there is a risk that the date entered is incorrect. It doesn't work like an input mask. So i need to validate the date in the code.
{
type: "datetime",
label: "Date:",
name: "Date",
def: function () { return new Date(); },
format: 'MM/YYYY',
fieldInfo: 'Format: Month/Year (ex: 12/2022)',
keyInput: true
}
The date should not be accepted if the difference between this date and today's date is less than 3 months.
It means that, compared to today, all dates before July will have to be rejected.
Currently I can do this with the relativedelta method of the python dateutil module. But as the validation must be done on the client side, I would like to do this in javascript (which I know very little).
The example below shows how to do this. You should take advantage of the HTML 5 input types to validate your dates. You also need to calculate 3 months from now in myEpoch and then compare it to the date/time given
HTML:
<p>
Date & Time: <input id="foo" type="datetime-local" />
</p>
JavaScript:
var myEpoch = new Date();
myEpoch.setMonth(myEpoch.getMonth() + 3);
myEpoch = myEpoch.getTime();
var foo = document.getElementById("foo");
if (foo.value < myEpoch) {
//show a message saying this date is invalid
}
Since user is entering date in MM/yyyy format, so i'm assuming that you take 1 as a date into account, i.e., if input is 03/2020, you would consider it as: 01/03/2020. Right? If
so, then you can do the following to validate this date:-
function isValidDate(inputDate) {
// Unfortunately JS doesn't have any in-built function to validate date in MM/yyyy format. Hence regex comes to the rescue
var regex = /^([0-9]{1,2})\/([0-9]{4,4})$/;
var matches = regex.exec(inputDate);
if (!matches || matches.length != 3) {
throw new Error('Please provide date in MM/yyyy format');
}
var inputMonth = matches[1]; // Return month from input date
var inputYear = matches[2]; // Return year from input date
var finalDate = inputMonth+ '/01/' + inputYear;
// Check if entered date is valid or not
var parsedDate = Date.parse(finalDate);
if (isNaN(parsedDate)) {
throw new Error('Unable to parse date.');
}
// Check if it is less than 3 months or not.
var isValid = !isLessThan3Months(new Date(finalDate), new Date());
return isValid;
}
function isLessThan3Months(dateToCompare, currentDate) {
var diffYears = currentDate.getFullYear() - dateToCompare.getFullYear();
var diffMonths = currentDate.getMonth() - dateToCompare.getMonth();
var diffDays = currentDate.getDate() - dateToCompare.getDate();
var months = diffYears * 12 + diffMonths;
if (diffDays > 0) {
months += '.' + diffDays;
} else if (diffDays < 0) {
months--;
months +=
'.' +
(new Date(currentDate.getFullYear(), currentDate.getMonth(), 0).getDate() + diffDays);
}
return months < 3;
}
isValidDate('03/2020');
So now, by calling isValidDate with user's input date in MM/yyyy format, you should be able to check if it is valid or not.
For this, you won't need to use any third party javascript library. Just plain javascript is enough.
You should probably use Moment.js, because working with the raw Date object is fiddly.
If you would rather use plain JavaScript, then the following might be of use:
const moreThan3MonthsHence = ({ utcYear, utcMonth },
now = new Date,
target = new Date(Date.UTC(utcYear, utcMonth)),
threeMonthsHence = addMonths(new Date(now.valueOf()), 3)) =>
(target > threeMonthsHence)
const validate = (str,
[utcMonth, utcYear] = str.split('/'),
date = new Date(Date.UTC(+utcYear, (+utcMonth)-1))) =>
moreThan3MonthsHence({ utcYear: date.getUTCFullYear(), utcMonth: date.getUTCMonth() })
const addMonths = (date, months, d = date.getDate()) => {
date.setMonth(date.getMonth() + +months);
// If rolled over to next month, set to last day of previous month
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
// Note: input is one-based months
console.log(validate('07/2020')) // true
console.log(validate('06/2020')) // false
console.log(validate('12/2019')) // false
Notes
now is internally represented as the milliseconds since the Unix epoch. Note this includes the current time of day.
target is the milliseconds since the Unix epoch of midnight on the supplied UTC date.
threeMonthsHence is the milliseconds since the Unix epoch of now (including time of day), plus three months.
validate parses the input string.
addMonths is necessary because the built-in function can roll-over into a new month with unexpected behavior.
Finally to solve my problem I mixed the solutions proposed by #Sumit Parakh and #ControlAltDel.
function isValidDate(inputDate) {
var regex = /^([0-9]{1,2})\/([0-9]{4,4})$/;
var matches = regex.exec(inputDate);
var parsedDate = 0;
if (!matches || matches.length != 3) {
throw new Error('Please provide date in MM/yyyy format');
}
else {
var inputMonth = matches[1]; // Return month from input date
var inputYear = matches[2]; // Return year from input date
var finalDate = inputMonth+ '/01/' + inputYear;
// Check if entered date is valid or not
var parsedDate = Date.parse(finalDate);
if (isNaN(parsedDate)) {
parsedDate = 0;
//throw new Error('Unable to parse date.');
}
return parsedDate;
}
var myEpoch = new Date();
myEpoch.setMonth(myEpoch.getMonth() + 3);
myEpoch = myEpoch.getTime();
finalDate = isValidDate(date_peremption.val());
if (finalDate == 0){
date_received.error("This date is invalid");
}
else if(finalDate < myEpoch) {
date_received.error("The date must be more than three months last");
}
It's not very elegant, but it works. Thanks everyone

inncorrect date validation when year like 'dd.mm.0302' or '27.08.0974' in JS

I have a problem with date validation from database, some years in the date fields are incorrect (like 28.02.0302), i must validate them. I try some functions from web but they validate this date as valid. How to get them work?
Here function that i tried:
function isValidDate(d) {
if ( Object.prototype.toString.call(d) !== "[object Date]" )
return false;
return !isNaN(d.getTime());
}
function isValidDate11(s) {
// format D(D)/M(M)/(YY)YY
var dateFormat = /^\d{1,4}[\.|\/|-]\d{1,2}[\.|\/|-]\d{1,4}$/;
if (dateFormat.test(s)) {
// remove any leading zeros from date values
s = s.replace(/0*(\d*)/gi,"$1");
var dateArray = s.split(/[\.|\/|-]/);
// correct month value
dateArray[1] = dateArray[1]-1;
// correct year value
if (dateArray[2].length<4) {
// correct year value
dateArray[2] = (parseInt(dateArray[2]) < 50) ? 2000 + parseInt(dateArray[2]) : 1900 + parseInt(dateArray[2]);
}
var testDate = new Date(dateArray[2], dateArray[1], dateArray[0]);
if (testDate.getDate()!=dateArray[0] || testDate.getMonth()!=dateArray[1] || testDate.getFullYear()!=dateArray[2]) {
return false;
} else {
return true;
}
} else {
return false;
}
}
Because the date you are trying: 28.02.0302 with your script actually change that date to the 28 of February of the year 2202. So it's actually a valid date.
There are two part of that script that result in your date actually being checked as 2202:
This part remove leading Zeroes from the date values making the year from 0302 to 302.
// remove any leading zeros from date values
s = s.replace(/0*(\d*)/gi,"$1");
This second part check if the date is less than 4 characters and add 2000 if is less than 50 and 1900 if is more.
// correct year value
if (dateArray[2].length<4) {
// correct year value
dateArray[2] = (parseInt(dateArray[2]) < 50) ? 2000 + parseInt(dateArray[2]) : 1900 + parseInt(dateArray[2]);
}
The second part is a bit more tricky. I guess that it was made to validate a date of 01.01.12 as 01/01/2012 and a date of 01.01.93 as 01/01/1999
Those are not really necessary and you can change the function to:
function isValidDate11(s) {
// format D(D)/M(M)/(YY)YY
var dateFormat = /^\d{1,4}[\.|\/|-]\d{1,2}[\.|\/|-]\d{1,4}$/;
if (dateFormat.test(s)) {
var dateArray = s.split(/[\.|\/|-]/);
// correct month value
dateArray[1] = dateArray[1]-1;
var testDate = new Date(dateArray[2], dateArray[1], dateArray[0]);
if (testDate.getDate()!=dateArray[0] || testDate.getMonth()!=dateArray[1] || testDate.getFullYear()!=dateArray[2]) {
return false;
} else {
return true;
}
} else {
return false;
}
}
Still the date 28.02.0302 is valid because it get checked as the 28 of February of the year 302.
So to get an exact answer you should probably say exactly what you consider a valid date and what you don't.
Since you have trouble with 0302 I guess you might want a date with a 4 numbers year that doesn't have a leading zero:
function isValidDate11(s) {
// format D(D)/M(M)/YYYY
var dateFormat = /^\d{1,4}[\.|\/|-]\d{1,2}[\.|\/|-]\d{4}$/;
if (dateFormat.test(s)) {
// remove any leading zeros from date values
s = s.replace(/0*(\d*)/gi,"$1");
var dateArray = s.split(/[\.|\/|-]/);
// correct month value
dateArray[1] = dateArray[1]-1;
if(dateArray[2].length != 4){
return false;
}
var testDate = new Date(dateArray[2], dateArray[1], dateArray[0]);
if (testDate.getDate()!=dateArray[0] || testDate.getMonth()!=dateArray[1] || testDate.getFullYear()!=dateArray[2]) {
return false;
} else {
return true;
}
} else {
return false;
}
}
This will fix your 0302 year problem but will not work with a date ending with a year with only two carachters .14

How to test the Date, Month and Year entered as 2 Digits are valid?

In my form, a user can enter the date like this: 220875 (day, month, year).
Once they entered the details, I would like to test that the date is valid:
Month is from 1 to 12 inclusive.
The day entered is valid for the specified month.
How would I find out whether or not the values are correct and matching?
here is my attempt: (excerpt)
DateIsOk:function(value) { //220875 for example
var formatValue = value.match(/.{1,2}/g), //splting as 22 08 75
fieldDate = parseInt(formatValue[0]), //converting to num
fieldMonth = parseInt(formatValue[1]),
fieldYear = parseInt(formatValue[2]),
dayobj = new Date();
//test need to go here...
}
If it helps, here is a Live Demo.
It seems you use the DD/MM/YYYY format.
So you can easily use this ready-to-use code: http://www.qodo.co.uk/blog/javascript-checking-if-a-date-is-valid/
JavaScript
// Checks a string to see if it in a valid date format
// of (D)D/(M)M/(YY)YY and returns true/false
function isValidDate(s) {
// format D(D)/M(M)/(YY)YY
var dateFormat = /^\d{1,4}[\.|\/|-]\d{1,2}[\.|\/|-]\d{1,4}$/;
if (dateFormat.test(s)) {
// remove any leading zeros from date values
s = s.replace(/0*(\d*)/gi,"$1");
var dateArray = s.split(/[\.|\/|-]/);
// correct month value
dateArray[1] = dateArray[1]-1;
// correct year value
if (dateArray[2].length<4) {
// correct year value
dateArray[2] = (parseInt(dateArray[2]) < 50) ? 2000 + parseInt(dateArray[2]) : 1900 + parseInt(dateArray[2]);
}
var testDate = new Date(dateArray[2], dateArray[1], dateArray[0]);
if (testDate.getDate()!=dateArray[0] || testDate.getMonth()!=dateArray[1] || testDate.getFullYear()!=dateArray[2]) {
return false;
} else {
return true;
}
} else {
return false;
}
}
If you don't mind using momentjs as #hVostt suggested, you could try modifying your DateIsOk() validation function like this:
...
dateParts : ["years", "months", "days", "hours", "minutes", "seconds", "milliseconds"],
DateIsOk:function(value) {
var dayobj = moment(value, "DDMMYY");
if (dayobj.isValid()) {
this.errorHandler(true);
return true;
}
else {
this.errorHandler('Invalid ' + this.dateParts[dayobj.invalidAt()]);
return false;
}
}
...
Here's the updated Live Demo
The js regexp maybe like this
/([0-2][0-9]|3[01])(0[1-9]|1[0-2])(\d{2})/
Please try Moment.js and his validation functions:
http://momentjs.com/docs/#/parsing/is-valid/
moment([2014, 25, 35]).isValid();
moment("2014-25-35").isValid();

How to validate date user input in javascript on mm:dd:yy format

I tried validating date with the following code:-
function d(id){
var n= document.getElementById(id);
var re=/^(?:(0[1-9]|1[012])[\- \/.](0[1-9]|[12][0-9]|3[01])[\- \/.](19|20)[0-9]{2})$/;
if (re.test(n.value))
{
n.style.backgroundColor="#52F40C";
}
else
{
window.alert("Invalid date");
n.style.backgroundColor="#F40C0C";
n.focus();
n.value="";
}
}
But it isn't working. What is the problem with this code?
try this
function isValidDate(subject){
if (subject.match(/^(?:(0[1-9]|1[012])[\- \/.](0[1-9]|[12][0-9]|3[01])[\- \/.](19|20)[0-9]{2})$/)){
return true;
}else{
return false;
}
}
Try to use this function
function isDate(txtDate, separator) {
var aoDate, // needed for creating array and object
ms, // date in milliseconds
month, day, year; // (integer) month, day and year
// if separator is not defined then set '/'
if (separator === undefined) {
separator = '/';
}
// split input date to month, day and year
aoDate = txtDate.split(separator);
// array length should be exactly 3 (no more no less)
if (aoDate.length !== 3) {
return false;
}
// define month, day and year from array (expected format is m/d/yyyy)
// subtraction will cast variables to integer implicitly
month = aoDate[0] - 1; // because months in JS start from 0
day = aoDate[1] - 0;
year = aoDate[2] - 0;
// test year range
if (year < 1000 || year > 3000) {
return false;
}
// convert input date to milliseconds
ms = (new Date(year, month, day)).getTime();
// initialize Date() object from milliseconds (reuse aoDate variable)
aoDate = new Date();
aoDate.setTime(ms);
// compare input date and parts from Date() object
// if difference exists then input date is not valid
if (aoDate.getFullYear() !== year ||
aoDate.getMonth() !== month ||
aoDate.getDate() !== day) {
return false;
}
// date is OK, return true
return true;
}

Regular expression for date format- dd-mm-yyyy in Javascript

I need a regular expression for date format: dd-mm-yyyy in Javascript.
function parseDate(str) {
var m = str.match(/^(\d{1,2})-(\d{1,2})-(\d{4})$/);
return (m) ? new Date(m[3], m[2]-1, m[1]) : null;
}
Notice
Your regexp does not work for years that "are multiples of 4 and 100, but not of 400". Years that pass that test are not leap years. For example: 1900, 2100, 2200, 2300, 2500, etc. In other words, it puts all years with the format \d\d00 in the same class of leap years, which is incorrect. – MuchToLearn
So it works properly only for [1901 - 2099] (Whew) 😊
dd-MM-yyyy
Checks if leap year.
Years from 1900 to 9999 are valid. Only dd-MM-yyyy
var stringToValidate = "29-02-2012";
var rgexp = /(^(((0[1-9]|1[0-9]|2[0-8])[-](0[1-9]|1[012]))|((29|30|31)[-](0[13578]|1[02]))|((29|30)[-](0[4,6,9]|11)))[-](19|[2-9][0-9])\d\d$)|(^29[-]02[-](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)/;
var isValidDate = rgexp.test(stringToValidate);
Here is Regex for multiple date formats working for me :
//dd.MM.yyyy
var date_regex = /^(0[1-9]|1\d|2\d|3[01])\.(0[1-9]|1[0-2])\.(19|20)\d{2}$/;
alert(date_regex.test("02.02.1991"));
// //dd/mm/yyyy
// var date_regex = /^(0[1-9]|1\d|2\d|3[01])\/(0[1-9]|1[0-2])\/(19|20)\d{2}$/;
// alert(date_regex.test("02/12/1991"));
// //dd-mm-yyyy
// var date_regex = /^(0[1-9]|1\d|2\d|3[01])\-(0[1-9]|1[0-2])\-(19|20)\d{2}$/;
// alert(date_regex.test("02-12-1991"));
// //mm/dd/yyyy
// var date_regex = /^(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])\/(19|20)\d{2}$/;
// alert(date_regex.test("12/02/1991"));
// //yyyy.MM.dd
// var date_regex = /^((19|20)\d{2})\.(0[1-9]|1[0-2])\.(0[1-9]|1\d|2\d|3[01])$/;
// alert(date_regex.test("1991.12.02"));
// //yyyy/MM/dd
// var date_regex = /^((19|20)\d{2})\/(0[1-9]|1[0-2])\/(0[1-9]|1\d|2\d|3[01])$/;
// alert(date_regex.test("1991/12/02"));
// //yyyy-MM-dd
// var date_regex = /^((19|20)\d{2})\-(0[1-9]|1[0-2])\-(0[1-9]|1\d|2\d|3[01])$/;
// alert(date_regex.test("1991-12-02"));
Try this:
'01-01-2012'.match( /\d{2}-\d{2}-\d{4}/ )
Note that that this way the date 33-12-2022 would be considered valid as well!
'01-01-2012'.match( /(?!3[2-9]|00|02-3[01]|04-31|06-31|09-31|11-31)[0-3][0-9]-(?!1[3-9]|00)[01][0-9]-(?!10|28|29)[12][089][0-9][0-9]/ )
This looks for only valid dates from 1800 to 2099. No leap year support (as in it assumes every year is a possible leap year).
Well, I made this:
'31-12-1987'.match(/(3[01]|[2][0-9]|0\d)-(1[0-2]|0\[1-9])-\d{4}/)
Validates the day from 01 to 31, month from 01 to 12 and year of four digits. It only fails the february 30, and the months without 31 days. Which you can clean using the new Date('mm/dd/yyyy').
This regex is for MM/DD/YYYY and M/D/YYYY
var date_regex = /^(0?[1-9]|1[012])[\/](0?[1-9]|[12][0-9]|3[01])[\/]\d{4}$/;
Working a few of the above together (primarily #gdZeus's) now you can do MM/dd/yyyy | MM-dd-yyyy | MM.dd.yyyy
/(^(((0[1-9]|1[012])[-/.](0[1-9]|1[0-9]|2[0-8]))|((0[13578]|1[02])[-/.](29|30|31))|((0[4,6,9]|11)[-/.](29|30)))[-/.](19|[2-9][0-9])\d\d$)|(^02[-/.]29[-/.](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)/
Additionally if you are using this inline in a js file you can use the following which returns a regexp literal. This will allow you to validate that a date is in the past! This is handy for birthdays. You can reverse it to check that a date is in the future as well (ex. checking credit card exp). This will work almost anywhere in javascript but not if you really need a regexp literal. For example if you are serializing it to a some other format without the ability to run js.
new RegExp('(^(((0[1-9]|1[012])[-/.](0[1-9]|1[0-9]|2[0-8]))|((0[13578]|1[02])[-/.](29|30|31))|((0[4,6,9]|11)[-/.](29|30)))[-/.]('+range(1920, new Date().getFullYear()).join('|')+')$)|(^02[-/.]29[-/.]('+range(1920, new Date().getFullYear()).filter(function(year){if (year % 4 == 0) { return true }}).join('|')+')$)/', 'g')
returns:
/(^(((0[1-9]|1[012])[-\/.](0[1-9]|1[0-9]|2[0-8]))|((0[13578]|1[02])[-\/.](29|30|31))|((0[4,6,9]|11)[-\/.](29|30)))[-\/.](1920|1921|1922|1923|1924|1925|1926|1927|1928|1929|1930|1931|1932|1933|1934|1935|1936|1937|1938|1939|1940|1941|1942|1943|1944|1945|1946|1947|1948|1949|1950|1951|1952|1953|1954|1955|1956|1957|1958|1959|1960|1961|1962|1963|1964|1965|1966|1967|1968|1969|1970|1971|1972|1973|1974|1975|1976|1977|1978|1979|1980|1981|1982|1983|1984|1985|1986|1987|1988|1989|1990|1991|1992|1993|1994|1995|1996|1997|1998|1999|2000|2001|2002|2003|2004|2005|2006|2007|2008|2009|2010|2011|2012|2013|2014|2015)$)|(^02[-\/.]29[-\/.](1920|1924|1928|1932|1936|1940|1944|1948|1952|1956|1960|1964|1968|1972|1976|1980|1984|1988|1992|1996|2000|2004|2008|2012)$)\//g
NOTE: this utilizes underscore's range function to generate the dates. You can write your own though like this very inelegant version :)
function range(start, end) {
var foo = [];
for (var i = start; i <= end; i++) {
foo.push(i);
}
return foo;
}
$('#DOB').blur(function () {
var s = $('#DOB').val(); alert('Entered date is:' + s);
var parms = s.split(/[\.\-\/]/);
var yyyy = parseInt(parms[2], 10);
var d = new Date();
var n = d.getFullYear(); //alert('current year is :' + n);
if (yyyy > n || yyyy < 1900) {
alert('Improper date format, Please enter dd/mm/yyyy format. (invalid year)');
}
var mm = parseInt(parms[1], 10);
if (mm > 12 || mm < 0)
{
alert('Improper date format, Please enter dd/mm/yyyy format. (invalid month');
}
var dd = parseInt(parms[0], 10);
if (dd > 31 || dd < 0)
{
alert('Improper date format, Please enter dd/mm/yyyy format. (invalid day');
}
//var date = new Date(dd, mm - 1, yyyy, 12, 0, 0, 0);
//var ndate = (date.getMonth() + 1) && ddmm === date.getDate() && yyyy === date.getFullYear();
// alert('new date is:' + ndate);
});
This works for me
new RegExp('^(0[1-9]|[1-9]|[12][0-9]|3[01])-(0[1-9]|[1-9]|1[012])-(19|20)\\d\\d$')
/^(\d{1,2})(\/)(\d{1,2})\2(\d{4})\$/

Categories

Resources