1

I have a value that may be a stringified date, or number. I'd like to handle each case differently.

Date values can be any valid date string that can be parsed by a date library, like dayjs. For example: "10/10/2020", "10-20-2020"...

Number values can be actual numbers, or numbers in the form of a string, so values like 5, "5.3", "10"...

For example ->


      const number = parseFloat(value);
      if (!isNaN(number)) {
          return NumberValueConverter.prototype.toView(number);
      }

      const date = dayjs(value);
      if (date.isValid()) {
          return DateValueConverter.prototype.toView(value);
      }

This code isn't working though - since date strings like 10-10-2020, 10-10-2020 end up getting parsed to 10

If I do it in reverse, dayjs converts numbers like 10 to a valid date.

twoLeftFeet
  • 693
  • 1
  • 5
  • 25
  • 1
    Don't use `parseFloat` at all, just `isNaN(value)`. It will return whether the conversion produces a valid number or not. `isNaN("10-10-2020")` is `true` – VLAZ Mar 18 '21 at 16:01
  • [(Built-in) way in JavaScript to check if a string is a valid number](https://stackoverflow.com/q/175739) – VLAZ Mar 18 '21 at 16:10
  • 1
    This isn't necessarily possible considering *all* date formats. For example, `20210318` is a valid date representation in ISO 8601 basic format. It is also a valid number. (`2021-03-18` is the ISO 8601 *extended* date format.) – Matt Johnson-Pint Mar 18 '21 at 16:44
  • @MattJohnson-Pint that's fair. I don't anticipate having 100% success with this - these are user input values that get stored in JSON - I'm mostly looking for a best effort sort of method that will return a fairly useful result to display most of the time to the end user. – twoLeftFeet Mar 18 '21 at 16:58

3 Answers3

1

parseFloat is already happy when the given string starts with a digit, so if you then test isNaN on that result, you'll get false positives.

So don't check whether the result is numeric, but whether the original string represents a number:

if (!isNaN(number)) {

to:

if (!isNaN(value)) {

Alternatively, you can use the unary plus instead of parseFloat, which will only return a definite number when the input represents a number:

const number = +value;

... and then it is best practice to test with Number.isNaN:

if (!Number.isNaN(number)) {
trincot
  • 317,000
  • 35
  • 244
  • 286
1
if(/^[0-9]+[.]{0,1}[0-9]*$/.test(value)) {
     // Handle your number value
} else {
     // Check for date here
}

You can use above regular expression for parsing number string.

  • /^ : Refers to start your string
  • $/ : Refers to end of your string
  • [0-9]+ : Starting of string is from 0 to 9 with minimum one length
  • [.]{0,1} : Can contain 0 or at max 1 '.'
  • [0-9]* : Can contain 0 to 9 digits at the end of string.
1

You could use regex to test if the string looks like a date before mapping. This regex is from https://www.regextester.com/96683 And it tests if it looks like the date you passed in.

There is more complex regex that tests for different formats of date if you do not know the format beforehand: https://stackoverflow.com/a/15504877/14948219

 if(([12]\d{3}/(0[1-9]|1[0-2])/(0[1-9]|[12]\d|3[01])).test(value)){
    return date
 } else if(isNan(value){
    return number
    
 }
Callum
  • 11
  • 3