Evaluation and type conversion issues



The following sections explain several issues that you can encounter with type evaluation and conversion.

Comparing variables to True or False

You might expect the following two cfif tag examples to produce the same results:

<cfif myVariable> 
    <cfoutput>myVariable equals #myVariable# and is True  
    </cfoutput> 
</cfif> 
<cfif myVariable IS True> 
    <cfoutput>myVariable equals #myVariable# and is True  
    </cfoutput> 
</cfif>

However, if myVariable has a numeric value such as 12, only the first example produces a result. In the second case, the value of myVariable is not converted to a Boolean data type, because the IS operator does not require a specific data type and just tests the two values for identity. Therefore, ColdFusion compares the value 12 with the constant True. The two are not equal, so nothing is printed. If myVariable is 1, "Yes", or True, however, both examples print the same result, because ColdFusion considers these to be identical to Boolean True.

If you use the following code, the output statement does display, because the value of the variable, 12, is not equal to the Boolean value False:

<cfif myVariable IS NOT False> 
    <cfoutput>myVariable equals #myVariable# and IS NOT False 
    </cfoutput> 
</cfif>

As a result, use the test <cfif testvariable>, and not use the IS comparison operator when testing whether a variable is True or False. This issue is a case of the more general problem of ambiguous type expression evaluation, described in the following section.

Ambiguous type expressions and strings

When ColdFusion evaluates an expression that does not require strings, including all comparison operations, such as IS or GT, it checks whether it can convert each string value to a number or date-time object. If so, ColdFusion converts it to the corresponding number or date-time value (which is stored as a number). It then uses the number in the expression.

Short strings, such as 1a and 2P, can produce unexpected results. ColdFusion can interpret a single "a" as AM and a single "P" as PM. This can cause ColdFusion to interpret strings as date-time values in cases where this was not intended.

Similarly, if the strings can be interpreted as numbers, you can get unexpected results.

For example, ColdFusion interprets the following expressions as shown:

Expression

Interpretation

<cfif "1a" EQ "01:00">

If 1:00am is 1:00am.

<cfif "1P" GT "2A">

If 1:00pm is later than 2:00am.

<cfset age="4a">

<cfset age=age + 7>

Treat the variable age as 4:00 am, convert it to the date-time value 0.16666666667, and add 7 to make it 7.16666666667.

<cfif "0.0" is "0">

If 0 is 0.

To prevent such ambiguities when you compare strings, use the ColdFusion string comparison functions Compare and CompareNoCase, instead of the comparison operators.

You can also use the IsDate function to determine whether a string can be interpreted as a date-time value, or to add characters to a string before comparison to avoid incorrect interpretation.

Date-time functions and queries when ODBC is not supported

Many CFML functions, including the Now, CreateDate, CreateTime, and CreateDateTime functions, return date-time objects. ColdFusion creates Open Database Connectivity (ODBC) timestamp values when it converts date-time objects to strings. As a result, you can get unexpected results when using dates with a database driver that does not support ODBC escape sequences, or when you use SQL in a query of queries.

If you use SQL to insert data into a database or in a WHERE clause to select data from a database, and the database driver does not support ODBC-formatted dates, use the DateFormat function to convert the date-time value to a valid format for the driver. This rule also applies to queries of queries.

For example, the following SQL statement uses the DateFormat function in a query of queries to select rows that have MyDate values in the future:

<cfquery name="MyQofQQ" dbtype="query"> 
SELECT *  
FROM DateQuery 
WHERE MyDate >= '#DateFormat(Now())#' 
</cfquery>

The following query of queries fails with the error message “Error: {ts is not a valid date,” because the ColdFusion Now function returns an ODBC timestamp:

<cfquery name="MyQofQQ" dbtype="query"> 
SELECT *  
FROM DateQuery 
WHERE MyDate >= '#now()#' 
</cfquery>

Using JavaCast with overloaded Java methods

You can overload Java methods so a class can have several identically named methods that differ only in parameter data types. At run time, the Java virtual machine attempts to resolve the specific method to use, based on the types of the parameters passed in the call. Because ColdFusion does not use explicit types, you cannot predict which version of the method the virtual machine will use.

The ColdFusion JavaCast function helps you ensure that the right method executes by specifying the Java type of a variable, as in the following example:

<cfset emp.SetJobGrade(JavaCast("int", JobGrade))>

The JavaCast function takes two parameters: a string representing the Java data type and the variable whose type you are setting. You can specify the following Java data types: Boolean, int, long, float, double, and String.

For more information on the JavaCast function, see the CFML Reference.

Using quotation marks

To ensure that ColdFusion properly interprets string data, surround strings in single- or double-quotation marks. For example, ColdFusion evaluates “10/2/2001” as a string that can be converted into a date-time object. However, it evaluates 10/2/2001 as a mathematical expression, 5/2001, which evaluates to 0.00249875062469.