Jeremy W. Sherman

stay a while, and listen

Dollars, Not Donuts

Internationalization is hard. If you’ve always lived where you have to travel to another continent to encounter something other than your local monoculture (hello, many fellow Americans), it’s even harder.

Perhaps it should be no surprise then that everyone gets it wrong. Over and over, I see the same amateur mistakes. Two seconds using your app in some locale other than the one you developed in would make you go, “Oh. Crap.”

Home Depot accepts Swedish kronor now?

Today’s mistake is “localizing” currency amounts in your application.

Take a look at this prime shot from the Home Depot website this morning:

Home Depot product listing shows price as Swedish kronor, even though the amount is clearly US dollars.

I’m sending sv-SE as my preferred language, so I get back the site’s closest approximation to Swedish in Sweden as possible. Oh, how cool, that includes converting currencies to Swedish kronor!

Oh wait, no it doesn’t. They just rigged up their currency formatter wrong. The formatter thinks the amount they specified – an amount actually in US dollars – must be Swedish kronor (SEK), because they didn’t tell it anything more specific, and so the formatter printed the amount as SEK.

I ran into this same thing when I went to renew my car insurance. A whole table of US dollar amounts formatted as Swedish kronor.

Table of auto insurance coverage. All prices are listed as Swedish kronor, even though it

This happens so often, across both websites and apps, that when I encounter something that actually does support displaying actual honest-to-God SEK amounts, I still assume it’s USD misrepresented as SEK until I realize the prices are wildly different from what the USD amount would be. This is so rare that it’s only happened once: thank you, Kayak, for getting this right!

If the exchange rate weren’t so far from 1 between USD and SEK (currently about 6 SEK to 1 USD), I don’t know how I’d be able to tell whether an app got it wrong or got it right.

This amateur mistake, repeated across vendors, applications, and platforms, makes for a terrible user experience for anyone working in a different region, even if they speak the same language as you.

It’s easy to get it wrong

Let’s see, how would you format a currency amount, say, $1,234.59 USD? How’s about this:

id amount = [NSDecimalNumber
             decimalNumberWithMantissa:123459
             exponent:-2 isNegative:NO];
NSString *display = [NSNumberFormatter
                     localizedStringFromNumber:amount
                     numberStyle:NSNumberFormatterCurrencyStyle];
NSLog(@"%@", display);

Very easy, right? And very wrong. That prints, “1 234,59 kr”.

Well, let’s try rigging up the currency formatter ourselves, eh?

NSNumberFormatter *fmt = [NSNumberFormatter new];
[fmt setNumberStyle:NSNumberFormatterCurrencyStyle];
[fmt setGeneratesDecimalNumbers:YES];

NSString *formattedAmount = [fmt stringFromNumber:amount];
NSLog(@"%@", formattedAmount);

Nope, still prints “1 234,59 kr”. This is likely exactly what the “convenience” converter did for us, minus the configuration setting to convert strings to decimal numbers. So that’s a lot of hoopla for no gain.

But not hard to get it right

But it just takes one more line to get it right. You need to tell the formatter what exactly it’s formatting. Raw numbers aren’t enough: it needs to know the currency you’re giving it. Like so:

NSNumberFormatter *fmt = [NSNumberFormatter new];
[fmt setNumberStyle:NSNumberFormatterCurrencyStyle];
[fmt setGeneratesDecimalNumbers:YES];
[fmt setCurrencyCode:@"USD"];

NSString *formattedAmount = [fmt stringFromNumber:amount];

Yup, it just takes a setCurrencyCode: message, and all is right with the world. This version here prints “1 234,59 US$” when using the Swedish region. The currency symbol follows the amount, as is usual in that region, and the separators for thousands and decimal are localized, as well.

Testing

Testing this is dead easy. You don’t even have to abandon your beloved mother tongue! Just change your region settings to something different. Swedish in Sweden has triggered enough localization mistakes for me, but I’m sure many other locales get messed up just as readily.

Changing languages is awkward – iOS does this semi-reboot thing, and you have to restart Mac apps to get them to pick up the change – but region settings can be changed in a jif and changed back just as easily, without forcing you to wander through menus in a language you might not understand. So switching regions is the list you can do to test how your localization – even inadvertent localization – might be wrong.

Change your region setting like so:

  • iOS: Settings > General > International > Region Format > Swedish > Sweden
  • Mac: Settings > Language and Text > Region > Swedish > Sweden

On the Mac, you’ll probably need to tic the “Show all regions” box before you can choose a region that doesn’t use your top language choice.

Sum-Up

  • Distinguish between localizing presentation of an amount in a unit and both the presentation and the unit.
    • Compare 1 mile versus 1.6 kilometers: does using “1 km” instead of “1 mi” in a metric-using region really represent what you meant to communicate?
  • Declare the currency code to your currency-style number formatters.

    [numberFormatter setCurrencyCode:@"USD"];
    
  • Test your app in different locales.

    • Just because you’re not localizing doesn’t mean system components you’re using aren’t doing it wrong for you.