Duncan's blog

September 21, 2011

ColdFusion LSCurrencyFormat inserts hard spaces?

Filed under: Coldfusion — duncan @ 8:31 pm
Tags: , , , , , ,

Today I was doing some work with the LSCurrencyFormat function for the very first time. Along the way I discovered something slightly unexpected. If the locale you specify uses spaces for a thousands separator (e.g. French), then Adobe ColdFusion (no idea for Railo or BlueDragon), doesn’t just add a normal space, it uses a ‘hard’ space.

I wouldn’t have found this out at all if it wasn’t for the fact I was doing some unit tests with MXUnit at the time. My test case was something like this:

<cfset strPrice = lsCurrencyFormat("12345678.9", "none", "fr_FR")>
<cfset assertEquals("12 345 678,90",  strPrice)>

So initially that failed, giving me the useful message that
Expected ’12 345 678,90′ but received ’12 345 678,90′. These values should be the same.
Puzzling. I was doing this in Firefox; if I selected just the error message and then chose View Selection Source, I could see it actually said
Expected ’12 345 678,90′ but received ’12&nbsp;345&nbsp;678,90′.

Ahah, so I assumed it was inserting the ‘&nbsp;’ non-breaking space HTML entity into the value instead of just a normal single space. So I updated my unit test assertion to be like this:

<cfset assertEquals("12&nbsp;345&nbsp;678,90",  strPrice)>

But that also failed, and this time when checking the source, it said
Expected ’12&nbsp;345&nbsp;678,90′ but received ’12&nbsp;345&nbsp;678,90′.
Curiouser and curiouser!

So at this point, I decided to loop over the actual string returned by lsCurrencyFormat to examine it more closely:

<cfoutput>
	<cfset french = lsCurrencyFormat("12345678.90", "none", "fr_FR")>
	
	<cfloop index="i" from="1" to="#Len(french)#">
		<cfset char = mid(french, i, 1)>
		
		#char#:#Asc(char)#<br/>
	</cfloop>
</cfoutput>

Which produced output that looked like:

1:49
2:50
 :160
3:51
4:52
5:53
 :160
6:54
7:55
8:56
,:44
9:57
0:48

The normal HTML space is ASCII character 32. But in this case it’s inserting ASCII character 160, which the browser interprets as &nbsp;. So for my unit test to work, I’ll have to do something like:

<cfset assertEquals("12" & Chr(160) & "345" & Chr(160) & "678,90",  strPrice)>

Dunno why Adobe in their infinite wisdom (to be honest this probably dates back to Allaire or Macromedia) would use character 160 instead just a normal single space character 32. And I expect other locale-specific formatting functions must do the same thing.
I’m getting exactly the same results with java.text.DecimalFormatSymbols.getGroupingSeparator(), so I expect ColdFusion is using that functionality in the background.

I suppose it shouldn’t really cause any problems, apart from perhaps when you’re needing to unit test (or perhaps if parsing some HTML you’ve received by CFHTTP). Just, unexpected is all.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Blog at WordPress.com.

%d bloggers like this: