How to approach a problem to validate date using given date format, for example I wanted to give any date format to a ponent like:
<Input format={"DD-MM-YYYY"} />
or
<Input format={"YYYY-MM-DD"} />
or
<Input format={"MM/DD/YYYY"} />
I was trying to use bination of moment() but it was giving me true while my date wasn't finished during typing. I have to validate input date after the whole given format is typed in.
How to approach a problem to validate date using given date format, for example I wanted to give any date format to a ponent like:
<Input format={"DD-MM-YYYY"} />
or
<Input format={"YYYY-MM-DD"} />
or
<Input format={"MM/DD/YYYY"} />
I was trying to use bination of moment() but it was giving me true while my date wasn't finished during typing. I have to validate input date after the whole given format is typed in.
Share Improve this question asked Feb 20, 2021 at 17:30 admadm 1791 gold badge1 silver badge13 bronze badges 6-
You mean you want to bind the validation after the string has been entered? If so you want to bind it to
onblur
. But I am not 100% sure if that is what you are asking – lharby Commented Feb 20, 2021 at 17:42 - Binding is piece of cake. I was asking about is there any kinda easy way to validate string based on given pattern. Let's say, string is valid when it's meet the criteria in format prop. – adm Commented Feb 20, 2021 at 20:20
- You could try using regular expressions – axtck Commented Feb 20, 2021 at 20:33
- I know, but I wanted to not use em – adm Commented Feb 20, 2021 at 21:16
- You want to validate the input, as it is entered, based on 3 or more patterns? But you don't want to use Regex? Surely this means that various patterns will fit your criteria, but how will you know if the user is entering date, month or year? – lharby Commented Feb 20, 2021 at 21:43
3 Answers
Reset to default 3date-fns is lightweight lodash like utility functions library for dates.
isMatch is suitable to find if date matches given format.
you can install it with npm or yarn
npm install date-fns --save
# or
yarn add date-fns
and use isMatch as
import isMatch from 'date-fns/isMatch'
isMatch('02/11/2014', 'MM/dd/yyyy') // true
Regex can also do the job, but you need to do heavy lifting on it and maintain it.
You could try using regular expressions, the regular expression for a date in format DD-MM-YYYY is:
^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$
Now test the input against the regular expression:
import { useEffect, useState } from "react";
export default function App() {
const [date, setDate] = useState();
const [valid, setValid] = useState(false);
useEffect(() => {
// regex for DD-MM-YYYY
const regexddmmyyyy = /^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d$/;
if (regexddmmyyyy.test(date)) {
setValid(true);
} else {
setValid(false);
}
}, [date]);
const handleChanged = (e) => {
setDate(e.target.value);
};
return (
<div>
<input type="text" onChange={handleChanged} />
<p>{date}</p>
{valid ? <p>Valid</p> : <p>Invalid</p>}
</div>
);
}
Code sandbox example: https://codesandbox.io/s/dazzling-andras-xfbo6?file=/src/App.js
I believe this provides the most flexibility of formatting and solves issues like "01" getting parsed incorrectly as a date. It's also much more readable than Regex. Thoughts?
moment(value, ["MM-DD-YYYY", "M-DD-YYYY", "MM-D-YYYY", "M-D-YYYY", "MM-DD-YY", "M-DD-YY", "MM-D-YY", "M-D-YY", "YYYY-MM-DD", "YYYY-M-DD", "YYYY-MM-D", "YYYY-M-D", "MM/DD/YYYY", "M/DD/YYYY", "MM/D/YYYY", "M/D/YYYY", "MM/DD/YY", "M/DD/YY", "MM/D/YY", "M/D/YY", "YYYY/MM/DD", "YYYY/M/DD", "YYYY/MM/D", "YYYY/M/D"], true).isValid()