1

I am running the code below, checking if the string is a date. One of my input values is 'text' which returns the NaN value but my if clause does not work as expected.

function isDate(myDate) {
  console.log('myDate = ' + myDate);
  return Date.parse(new Date(myDate));
}

// var date1 = '1/5/22'; // good date
var date1 = 'test'; // bad date

var whatDate = isDate(date1);

console.log('date = ' + whatDate);

if (whatDate == 'NaN') {
  console.log('bad date');
} else {
  console.log('good date');
}
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
Eagles27
  • 35
  • 4
  • 1
    `NaN` isn't a string. Use `Number.isNaN(whatDate)` – Barmar Jan 13 '22 at 22:09
  • A check or test function especially if it is also carries the prefix `is` in its name should always return exclusively a boolean value. Thus the OP firstly would implement such a function in a way a user would expect it to work. Secondly the OP has do deal withe the `NaN` issue exactly once within the test function's implementation. – Peter Seliger Jan 13 '22 at 22:56
  • In `Date.parse(new Date(myDate))` either *Date.parse* or *new Date* is redundant. You should never leave parsing to the built–in parser unless you know the value is a format supported by ECMA-262 (essentially ISO 8601 or the format produced by *toString*). – RobG Jan 14 '22 at 02:34

3 Answers3

2

in your if statement you are checking if whatDate is equal to string "NaN". what you want to check whether whatDate is a number or not.

you can try

if (isNaN(whatDate))
Deniz Karadağ
  • 751
  • 3
  • 8
  • 1
    `whatDate === NaN` This won't work because `NaN` is special, in that, `NaN` will never equal itself (`NaN === NaN` gives `false`). – Marco Jan 13 '22 at 22:22
  • seems like it. I checked in console :D and edited it. never had to write NaN == NaN – Deniz Karadağ Jan 13 '22 at 22:25
1

You're almost there:

if(whatDate == 'NaN'){
    log.debug('bad date');
}else{
    log.debug('good date');
}

Instead of comparing whatDate to 'NaN' use the function isNaN():

if(isNaN(whatDate)){
    log.debug('bad date');
}else{
    log.debug('good date');
}

Alternatively, if you really want to compare to 'NaN' you first have to convert whatDate to a string:

if((whatDate + "") == 'NaN'){
    log.debug('bad date');
}else{
    log.debug('good date');
}

Is one possibility. Another way would be

if(whatDate.toString() == 'NaN'){
    log.debug('bad date');
}else{
    log.debug('good date');
}
Marco
  • 7,007
  • 2
  • 19
  • 49
0

The following answer, in addition to what already was explained about how to detect a NaN value, wants to reach further.

A check or test function especially if it also carries the prefix is in its name should always return exclusively a boolean value.

  • Thus the OP firstly would implement such a function in a way a user would expect it to work.
  • Secondly the OP had do deal with the NaN issue exactly once within the test function's implementation.

Edit according and thanks to the clarification of RobG

... and ... according to the ECMAScript's spec with instantiating a Date object, the argument passed to the constructor function will be parsed and assigned to the internal thisTimeValue slot. The number type of the latter is the NaN value for a non parsable (invalid) argument.

Any valueOf related operation does return the value of the internal thisTimeValue slot.

Any toString related operation will compute a date string format from the latter value. For a thisTimeValue of NaN the returned string value has to be 'Invalid Date'.

Thus a validation / test implementation could have been something like ...

function isParsableDateRepresentative(...args) {
  return String(new Date(...args)) !== 'Invalid Date';
}

... but preferably it should be closer to the next provided one ...

function isParsableDateRepresentative(...args) {
  return !Number.isNaN(new Date(...args).valueOf());
}

Tests:

function isParsableDateRepresentative(...args) {
  return !Number.isNaN(new Date(...args).valueOf());
}

console.log('new Date("1/5/22") ...', new Date("1/5/22"));
console.log(
  'isParsableDateRepresentative("1/5/22") ...',
  isParsableDateRepresentative("1/5/22")
);
console.log('\nnew Date("test") ...', new Date("test"));
console.log(
  'isParsableDateRepresentative("test") ...',
  isParsableDateRepresentative("test")
);
console.log('\nnew Date(new Date("test")) ...', new Date(new Date("test")));
console.log(
  'isParsableDateRepresentative(new Date("test")) ...',
  isParsableDateRepresentative(new Date("test"))
);

console.log('\nnew Date() ...', new Date());
console.log(
  'isParsableDateRepresentative() ...',
  isParsableDateRepresentative()
);
console.log('\nnew Date(null) ...', new Date(null));
console.log(
  'isParsableDateRepresentative(null) ...',
  isParsableDateRepresentative(null)
);
console.log('\nnew Date(undefined) ...', new Date(undefined));
console.log(
  'isParsableDateRepresentative(undefined) ...',
  isParsableDateRepresentative(undefined)
);
console.log('\nnew Date("") ...', new Date(""));
console.log(
  'isParsableDateRepresentative("") ...',
  isParsableDateRepresentative("")
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
Peter Seliger
  • 11,747
  • 3
  • 28
  • 37
  • Re "*the return value is a Date object with an internal string value of 'Invalid Date'*" Nope. Date objects only have one internal value, which is a number that is a valid [*time value*](https://262.ecma-international.org/#sec-time-values-and-time-range) or *NaN*, it's not a string. The string "Invalid Date" is produced by [*Date.prototype.toString*](https://262.ecma-international.org/#sec-date.prototype.tostring) if the *time value* is *NaN*. – RobG Jan 14 '22 at 05:51
  • PS, `String(new Date(...args)) !== 'Invalid Date';` would be much simpler as `isNaN(new Date(...args))`. However, the fact that a string is parsed to a valid time value does not mean it was parsed correctly, or that it was a valid date, or that the same string will be parsed to the same time value in other implementations. :-) – RobG Jan 14 '22 at 05:55
  • @RobG ... Thanks for clarifying, I've falsely believed for many years, that a `Date` instance always internally already features both representatives as values, the `thisTimeValue` number type (which would be returned with e.g. `valueOf`) and the corresponding string value of the abstract `ToDateString` operation. But i was wrong. Any `toString` related return value gets computed at the spot. – Peter Seliger Jan 14 '22 at 09:20
  • @RobG ... I edited/corrected my answer according to your clarification(s). Thanks again for having pointed to my lack of understanding in a truly professional way. – Peter Seliger Jan 14 '22 at 09:57