Copy link to clipboard
Copied
I know how to get around this, but I thought it was really odd and wonder if anyone can explain it.
<cfoutput>#replace('$1,000','$','','all')*100#</cfoutput>
This was in a system that processes payments. It is just supposed to determine how many cents are in the total. I would expect this to return EITHER 100000 or an error because the comma makes it an invalid number format. Instead, it returns 4273500! What the heck is that?
I confirmed this on CF9, CF10, and CF11. Lucee returns an error ("Can't cast 1,000 to integer"), as I would expect.
Of course, it was poor programming to allow the comma to come through to begin with. That has been resolved, but I am still wondering what CF is even doing to get that number.
By the way, someone donated $1,000 to a charity through this system and was actually charged $42,735!
Copy link to clipboard
Copied
That's a generous donation! I would have expected an error as well. That is strange.
Funnier, 8,000 and 1,8,000 also calculate into similar numbers and 0,000 throws a cannot parse into a number error -- the expected result of all the examples.
Copy link to clipboard
Copied
tSpark wrote:
I know how to get around this, but I thought it was really odd and wonder if anyone can explain it.
<cfoutput>#replace('$1,000','$','','all')*100#</cfoutput>
...By the way, someone donated $1,000 to a charity through this system and was actually charged $42,735!
$42735 - that is $1 for every single day that ever existed on the ColdFusion calendar, up until December 31, 2016. That is because, in essence, the *100 part is making your code to cast the string '1,000' to the date 31st December 2016. In fact, '1,000' is then cast to the number of days since ColdFusion's zero date, 30th December 1899.
Thus,
<cfoutput>#'1,000' + 0#</cfoutput>
results in 42735, which is the same as
<cfoutput>#datediff('d', createdate(1899,12,30), createdate(2016,12,31))#</cfoutput>
Similarly, '2,000'+0 is cast to the total number of days until the end of the first month. That is, until 31st January 2017. '3,000' + 0 is cast to the total number of days until the end of the second month. that is, until 28th February 2017. '4,000' + 0 is cast to the total number of days until the third month, that is, until 31st March 2017. And so on.
Another example:
'5,000' + 0: <cfoutput>#'5,000' + 0#</cfoutput><br>
datediff: <cfoutput>#datediff('d', createdate(1899,12,30), createdate(2017,4,30))#</cfoutput>
Both will give you 42855. Weird but true. The moral here is to be careful when using ambiguous values in a weakly-typed language like ColdFusion.
Copy link to clipboard
Copied
Yeah, there is a article here about how Coldfusion converts its data types - ColdFusion Help | Data type conversion
I have found though that if things look off, its most likely just converted to its go-to data type - date
If it represents a number (for example, "1,000" or "12.36E-12"), it is converted to the corresponding number. If it represents a date-time (see next column), it is converted to the numeric value of the corresponding date-time object.
Clearly doesn't do what it says it does though
Copy link to clipboard
Copied
Wow, go-to data type of date -- that is probably the last data type I would have expected. Strange, but I guess true.