IsNumeric vs IsValid

Here is an oddity spotted by my colleague David Boyer (MisterDai) the other day. Since Dave has been um, too busy to blog about it, and we worked through it together, I’m throwing up a quick post about our findings for posterity.

If you’ve been using Adobe ColdFusion for any length of time, you’re probably aware of the IsNumeric() function. It’s been around for ages (at least since I started using CF back with version 4.5) and does pretty much what you’d expect – if the value passed to it is numeric it returns true, otherwise it returns false.

More recently (MX 7), IsValid() was introduced. This is a more general-purpose function for validating data.  It takes an additional parameter, type, indicating which data type rule to apply to the supplied value. Specifying a type of numeric is, according to the CF9 documentation at least, equivalent to IsNumeric().

The problem is that they aren’t exactly equivalent.  Try the following:

<cfoutput>
	#IsNumeric('5a')#
	#IsValid('numeric', '5a')#
</cfoutput>

and you’ll see NO YES.

So why does IsValid() think 5a is a number? Well after a bit of experimentation (via establishing that although 5a is a number, 5b is not) we realized that it was interpreting 5a as a time (5am), 23p validates as a number while 24p does not. You can even use a full date like 2010-01-02 12:12:32 and it will validate as a number using IsValid()

Interestingly, the documentation for IsNumeric() doesn’t actually say that it determines whether the value is a number, but but whether it can be converted to a number, a subtle but important distinction. Oddly though, that seems to be a more accurate description of what IsValid() is doing – 5a can be converted to a number (0.208333333332) using JavaCast(), 24f cannot.

The moral of the story is that if you want a strict check on whether something is a number rather than something that can be converted to a number, use IsNumeric(), or use Railo instead ;)