2

I have lots of different strings from various sources, and I need to check if any of the string could be a valid date.

The problem is that there is no way to check if a string is a valid date for the following examples:

(I've tried both native javascript and moment.js. Nothing to do.)

const moment = require('moment');
const expectedDateFormat = ['DD-MM-YYYY','YYYY-MM-DD', moment.ISO_8601];

const examples = ['2019-03-31','2018-04-09T12:37:28Z','2013-02-04T22:44:30.652Z','28-10-2019','HAVTD-123224','HAVLF200974','1st action required','"$1445":3','On the night of Thursday May 17 2018 at 20:52 the vehicle was travelling Nord-Wesr when the impact occurred','HAVLF200323','HAVLF201037','HAVTD200110'];

const isValidDate = (string) => {
    const date = moment(string, expectedDateFormat)
    return date.isValid()
}

console.log('-----TRUE-----');
for (var i = 0; i< examples.length; i++) {
if(i == 4) 
console.log('-----FALSE-----');
    console.log(`${examples[i]} //`, isValidDate(examples[i]));
}


The first 4 strings only are valid Date. You can try to adjust and play the expectedDateFormat, it still won't work.

These are the actual result printed in the console:

-----TRUE-----
2019-03-31 // true
2018-04-09T12:37:28Z // true
2013-02-04T22:44:30.652Z // true
28-10-2019 // true
-----FALSE-----
HAVTD-123224 // false
HAVLF200974 // true
1st action required // true
"$1445":3 // true
On the night of Thursday May 17 2018 at 20:52 the vehicle was travelling Nord-Wesr when the impact occurred // true
HAVLF200323 // true
HAVLF201037 // true
HAVTD200110 // true

Try any javascript framework/function that you want, I challenge you to make this work.

1 Answers1

0

As with most languages, the built-in date parsing in Javascript is bad and should only be used for trivial things.

You should instead use a real date library such as https://momentjs.com/

Specifically, this feature is what you're looking for: https://momentjs.com/docs/#/parsing/is-valid/

const moment = require('moment')

const expectedDateFormat = "MM-DD-YYYY"

const example1 = '"$1445":3'
const example2 = 'HAVTD-123224'
const example3 = '10-28-2019'
const example4 = '1st action required'

const isValidDate = (string) => {

    const isStrict = true

    const date = moment(string, expectedDateFormat, isStrict)
    return date.isValid()
}

console.log("isValidDate example1", isValidDate(example1)) //false
console.log("isValidDate example2", isValidDate(example2)) //false
console.log("isValidDate example3", isValidDate(example3)) //true
console.log("isValidDate example4", isValidDate(example4)) //false

You need to specify the expected date format, as I've done above, to ensure consistent output in any environment. If there is more than one possible format, you can pass in a list of formats instead of just one.

Andrew Koster
  • 1,550
  • 1
  • 21
  • 31
  • 1
    @PatrickRoberts—implementation dependent results are not good, consistent behaviour. Even using the formats specified in ECMA-262 is not reliable. – RobG Sep 19 '19 at 20:14
  • @AndrewKoster thanks for the tips, but again, if you use the string "1st action required" it will say that is a valid date. So again, this is really weird, I can't test any string in the world, there must be a way to have it correct. – Alessandro Catania Sep 20 '19 at 12:31
  • @AlessandroCatania I just updated my answer. You want to specify a third parameter, after the date format, saying whether to use strict parsing. Not sure why it defaults to non-strict, but that solves the problem for the specific strings that you've specified. With actual strict parsing, it should work for all strings. – Andrew Koster Sep 21 '19 at 17:19
  • @PatrickRoberts If you don't specify strict parsing, the native `Date()` parsing is what it falls back to. As you can see, even complete nonsense strings like `"1st action required"` are considered valid, even with a date format specified. That is not "good" by most reasonable definitions, though it may be "consistent"ly bad. – Andrew Koster Sep 21 '19 at 17:22
  • @RobG do you have any evidence to suggest that restricting input to the formats specified results in non-compliant behavior? If so I'll retract my statement. – Patrick Roberts Sep 21 '19 at 17:36
  • This whole question is about validating input. Of course you don't need to validate input if you've already validated it. – Andrew Koster Sep 22 '19 at 22:55
  • @PatrickRoberts—try `new Date('2019-01-01T00:00:00')` in Safari and Firefox. You're also depending on reasonably current features, there are many devices in use that can't be updated to modern versions of ECMAScript engines, especially considering devices other than phones, tablets and PCs. – RobG Sep 23 '19 at 00:38
  • @RobG okay, so then Safari is compliant and Firefox isn't compliant in that case. I retract my statement. According to the specification, _when the UTC offset representation is absent... date-time forms are interpreted as a local time_ but Firefox interprets it as UTC time. – Patrick Roberts Sep 23 '19 at 01:14
  • @RobG please remove this as a duplicate since parsing data may be The solution, but the question and issue has nothing to do with parsing data, it is about validating string as date, not checking their date format. – Alessandro Catania Sep 26 '19 at 17:57
  • This is a useful, original question. People on this site see "duplicates" where there are none. – Andrew Koster Sep 26 '19 at 20:17
  • @AndrewKoster—I understand the question to be "how to parse non–standard date strings" where "non–standard" is any format not supported by ECMA-262. The answer is "use a parser and supply the date format". That should validate both the format and validity of the date. There are a number of existing libraries that will do the job, or you can write your own. There are also many questions about [*how to validate a date*](https://stackoverflow.com/search?q=%5Bjavascript%5D+how+to+validate+a+date). – RobG Sep 26 '19 at 21:05
  • @RobG please again, 1) This can be really usefull for stackOverflow users since it contains examples that were not used before 2) This seems a duplicated of parseDate where instead it "could be" a duplicate of "how to validate a date" (people that have to look for validation may not look directly on "parsing" 3) If you see the other questions on "how to validate a date" on the link you posted, you will see that there is not a correct solutions, like the one we found on this post. 4) Most of the posts don't talk about "string" validation as date, but as "date object" validation as date. – Alessandro Catania Oct 02 '19 at 15:42