Currency Internationalization (i18n), Multiple Currencies and Foreign Exchange (FX)

Internationalizing applications often involves changing currency units or supporting additional currencies simultaneously. As web-based applications are increasingly international in scope, I am frequently asked about supporting dual or multiple currencies. Here are some considerations. This is not intended as a detailed article or prescription for handling multiple currencies or foreign exchange, but it may give you some ideas for assessing your application requirements.


First Steps

Applications that support only one currency need to be adapted to record the currency along with the amount. Simple to say, but this can be a substantial effort to modify the database schema and all applications that reference the data, and all code that has the currency "hardcoded" (i.e. programmed directly into the software as a particular currency rather than looking up the currency associated without the amount.)

In addition, when redesigning the software to accommodate different or multiple currencies, the designer should be careful as to which aspects are determined either by user preference (which may in turn be indicated by locale), by regulation, by the nature of the application, or perhaps by other factors. The appropriate determining value(s) will need to be a part of the API. For example, the user may decide which character is used to separate the integer portion of a number from the fractional portion. That choice can be applied to the formatting of all currencies. On the other hand, a check printing application may have different requirements for formatting currencies from an application that lists financial transactions in a table. Regulations may determine how conversions are performed and how many significant digits are maintained throughout the calculations, which may in turn affect the display. (You don't want to display more digits than are significant.) Different programming models will use different approaches to communicating requirements thru the architecture (procedural, vs. object oriented, etc.)

Requirements for Multiple Currencies

A common misconception is that only one currency is desirable for any account. Although, this is more true in North America, it is not the case in other regions. For example, if you ask an american bank for an account that has both concurrent Canadian Dollar (CAD) and American Dollar (USD) balances, you will likely be given 2 separate account numbers. However in Europe, it is common that one account can have multiple currencies in the same way that one brokerage account can be used to buy multiple stocks.

Regulations for Foreign Exchange

Regulations of course vary by country. Some relevant organizations are listed in the Links section. Depending on your country, you may need to process multiple currencies in compliance with one of:

  • FASB Statement no. 52, Foreign Currency Translation,
  • Statements of Standard Accounting Practice 20 (the United Kingdom and Canadian authoritative pronouncement),
  • International Accounting Standard 21, Accounting for the Effects of Changes in Foreign Exchange Rates (the IASC's authoritative pronouncement),
  • the European Community EC Directives 4 (Annual Account of Certain Types of Companies) and 7 (Council Directive on Consolidated Accounts), or
  • other...

For an interesting matrix of foreign exchange features and accounting products, see Accounting Software Advisor, LLC article. (Some Progress ISV's mentioned.)

Foreign Exchange (FX) rates

Foreign Exchange or FX rates can be confusing. There are spot, forward, cross and other FX rates. You also need to be careful with how rates are quoted. The CAD/USD rate can be quoted in terms of CAD (eg. 1 CAD = .6 USD) or in terms of USD (eg. 1 USD = 1.5 CAD).

Many "good" systems allow users to enter Exchange Rates as needed. Some companies enter a default rate per month, and others have live feeds that enter rates as they change during the day. Note that many financial transactions are not instantaneous. As currency exchange rates fluctuate, the timing can be significant. Programs must be careful to acquire the exchange rate for the right date and time. Transactions that spread payments over time (sometimes years) may require multiple exchange rates.

Reports by currency

Multi-currency users will not be satisfied to simply sort reports by a single currency. For example, a list showing account and balance in USD, immediately followed by account and balance in CAD, followed by more USD, then more CAD, etc.

Instead, column totals should be divided into CAD and USD, with a final total converted to the local currency. This can be complicated to program, especially if there are many currencies involved.


Rounding in financial applications must follow local regulations. You may have learned the following rule to round numbers with fractional portions:

  • If the last digit is less than 5, drop it. Otherwise,
  • If the last digit is equal to or above 5, add one to the previous digit and drop the last digit.

By these rules, 6.011 rounds down to 6.01, and 6.015 rounds up to 6.02. However, these rules are not always appropriate in the financial world.
(The following rounding examples are based on Software Internationalization and Localization: An Introduction by Uren, Howard and Perinotti, Van Nostrand Reinhold, September 1993 ISBN 0-442-01498-8, page 27.)

For example, in Argentina rounding is prescribed for the third digit after the decimal point:

  • If the third digit is less than 3, change it to 0 or drop it. Otherwise,
  • If the third digit is both greater than 2 and less than 8, change it to 5. Otherwise,
  • If the third digit is greater than 7, add one to the second digit and drop the third digit or change it to 0.
Argentina Rounding Examples
Original NumberRounded ValueNotes
123.452123.45third digit<3, round down
123.456123.4552<third digit<8, change to 5
123.459123.46third digit>7, round up

Swiss rounding is like the conventional rule above, but offset by -.25:

  • If the last 2 digits are less than 26, change to 0. Otherwise,
  • If the last 2 digits are above 75, add one to the previous digit, and drop the last digits. Otherwise,
  • If the last 2 digits are greater than 25 and less than 76, replace the digits with 5.
Swiss Rounding Examples
Original NumberRounded ValueNotes
9.87129.879.87 covers 9.8676 to 9.8725
9.87319.8759.875 covers 9.8726 to 9.8775
9.87629.8759.875 covers 9.8726 to 9.8775
9.87819.889.88 covers 9.8776 to 9.8825

Note: Rounding does not always cause the precision (number of decimal places after the decimal point) to be reduced. In the second example for Argentina, there are 3 places both before and after rounding.

Note: Recognizing that rounding rules vary, programmers should NOT use the rounding API or procedures from their programming environment. (e.g. the C library routines). Instead, programmers should have a private API for rounding which they customize for the currency or locales they are working with.

Note: Here is a good reference on rounding in Asian countries. (China, Hong Kong, India, Indonesia, Japan, Korea, Malaysia, Philippines, Singapore, Thailand).

Note: Standards on number rounding include: ISO 31-0:1992 Annex B, IS 2, JIS Z 8401, KS A 0021


It is a well-understood problem in floating point computing that when adding many terms together of different sizes, that the smaller numbers may get "lost" among the bigger terms due to rounding. One solution is to add terms of like sizes. For example, a program might first sort all the values and then begin adding from small to large. This gives the smaller terms a chance to accumulate to significant values without being overshadowed by the larger terms. When internationalizing an application, bear this in mind. Values that are typical in one market, can be smaller or larger in other markets, and even greater discrepancies occur once currency exchange is taken into account. You may need to modify your application to add terms of like sizes, to prevent inaccuracies from occuring.

Another solution is to use decimal fixed point arithmetic, available in most programming environments and the choice of most financial and commercial applications. (Although Javascript does not have fixed point at the moment.) Fixed point arithmetic can be slower than floating point, but doesn't have the inaccuracy problem.

For more details on binary floating point and decimal fixed point, see the Frequently Asked Questions from this site on General Decimal Arithmetic.

Number Text Generation (check writing)

A common requirement for check writing (or cheque writing!) is to be able to spell out numbers. For example, "1234" becomes "one thousand, two hundred and thirty-four". The algorithm for spelling numbers is very simple in English, but is more difficult for other languages. Text generating programs have to address both different grammar rules and the ideosynchrasies of counting in different languages. It can be very difficult to make one algorithm support many languages.

For example, the text generation algorithm for Spanish is similar to English. The number names change of course, but the separator between the tens and ones place also changes change from hyphen to the word "y".

Word order can also change. In German, the ones digits precedes the tens place. E.g. "23" is "dreiundzwanzig" (literally, the concatenation of three-and-twenty.)

For a more detailed discussion of the internationalization issues with number text generation, and a rule-based solution, here is a paper by Richard Gillam, presented at the April, 1998 Unicode Conference and posted here with his kind permission: A Rule-Based Approach to Number Spellout. (253 kb, pdf)

(Rich is frequently published. See his web site for more of his articles. Rich is also the author of Unicode Demystified: A Practical Programmer's Guide to the Encoding Standard.)

Currency Conversion

There can be very specific accounting rules for currency conversion. In addition to how the conversion rate is determined, the precision (number of significant digits after the decimal point) may be specified. (more tbd.)


In the case of the euro, there are specific rules for calculation of cross-rates (the determination of an exchange rate in terms of two other exchange rates). (More tbd.)

Presentation Formats

Number formats determined by user preferences

Number formats vary around the world. The formats that should be employed are usually determined by user preferences, not by the currency being displayed. The format choice may also depend on the application. Number formatting includes separators (group and fractional), width and precision, digits (european, chinese, arabic, etc.). You may need to consider the preferences of your new international users. Currency formatting can affect number formats (see the example below where Swiss currency is formatted differently than Swiss numbers) and includes the placement of the currency designation (before or after the number) and whether it is a currency symbol, a 3-letter code, or a fuller description of the currency.

Grouping Separator

The integer portion of a number is often split into groups by a grouping separator. Western numbers generally separate numbers into thousands, or groups of 3 digits. However, other styles exist.

Chinese and Japanese number systems group 4 digits (groups of ten thousand). Traditionally, numbers are written in ideographic characters, with the character representing the appropriate unit size for 10s, 100s, 1000s, 10,000s after each digit. However, today numbers are often written using european digits (0-9), with only the ideographic characters representing powers of 10,000 inserted every 4 digits. The numbers in-between the ideographic characters may or may not use a comma or other separator for thousands. The table below gives an example with and without the comma separator. The character "" (pronounced "man" in Japanese) represents 10,000. Other characters are used for higher multiples of 10,000. E.g. "" (oku) is for 100,000,000, "" (chou) is for 1,000,000,000,000. See the table below for other Japanese Counting Characters.

Indian number format groups the lowest order 3 digits (thousands) and then every 2 digits after that.

Note that changing the group (or fractional) separator can interfere with list processing or other software functions. See the section on List Separators.

Grouping Examples
British1,234,567,890.12Groups of 3
12 3456 7890.12
12 3,456 7,890.12
Groups of 4, separated by ideographic characters and optionally a thousands separator.
Indian1,23,45,67,890.12One group of 3, then groups of 2
German1.234.567.890,12Groups of 3, separator is full-stop
Swiss1'234'567'890,12Groups of 3, separator is apostrophe1
French1 234 567 890,12Groups of 3, separator is a thin non-breaking space2 or "une espace fine insécable".
1 See the comments on Swiss numbers and currency in the section on fractional separators.
2 U+00A0 No-Break Space is often used. (&nbsp; in HTML.) You can read more about other spacing characters in the Unicode Consortium's chart on General Punctuation.
When choosing a group separator, take into account the impact on searching. Users cannot see the difference between breaking and non-breaking spaces, so if the search function treats them as separate, users may not search properly.

Japanese Counting Characters

Here are some of the characters used in Japanese counting. The characters man (10,000), oku (100,000,000) and chō (1,000,000,000,000) are in common usage, appearing regularly in Japanese newspapers and magazines. Their values are in the range where they can be relevant to budgets and fiscal discussion, for example. Today, some people may recognize the next two characters, kei and gai, but these two and those representing even larger units, almost never occur in actual modern text. Scientific discussion would, of course, revert to exponential notation. (E.g. 1.23 x 1024)

Japanese Counting Characters
Power of 1048 1216 20 24283236 404448
Character 禾予
Japanese Pronunciation man oku chō kei gai1 jo2 kan sei sai goku
Unicode Value U+4E07 U+5104 U+5146 U+4EAC U+5793 U+79BE
U+7A63 U+6E9D U+6F97 U+6B63 U+8F09 U+6975
1 The symbol for Gai (垓 U+5793 above) can also be represented by 該 U+8A72.
2 The symbol for Jo (禾予 U+79BE,U+4E88 above) is also called Shi. What should be a single glyph image is represented here by two characters. Historically, the Japanese character standard JIS 208 did not include a character for Jo, so it was represented by two characters. Jo can also be represented by the single Unicode character 秭 U+79ED or the pair of Unicode characters 禾市 U+79BE,U+5E02; When the characters of Extension B in Unicode 4.0 are more widely supported, you may be able to use any of the three supplementary characters U+25771, U+25797, or U+25791 for Jo. Here is a 13Mb Acrobat PDF file, where you can see the characters of Extension B.
There is also more information (in Japanese) on Jo/Shi here.

Fractional Separators

The separator between integer and fractional parts of a number (known as a decimal point, fractional separator, decimal separator and other terms) can be a full-stop (also known as a decimal point or period) or a comma, or other characters. Portuguese Escudos used a dollar sign as a fractional separator. Note that the Swiss use a different fractional separator for number and currency amounts.¹

Fractional Separator (Decimal Point) Examples
Portuguese Escudos12$34ESCFractional separator is dollar sign
German Deutsch Marks12,34DMFractional separator is comma
Canadian Dollars (English)$12.34Fractional separator is full-stop
Canadian Dollars (French)12,34 $Fractional separator is comma
Swiss Numbers12'345,67Fractional separator is comma
Swiss FrancsSFr 12'345.67Fractional separator is full-stop
¹ This is according to the book by IBM, NLS Information & Design Guide Vol 2, Reference Manual, SE09-8002, page 49:
"Switzerland uses a comma as the decimal separator, except when the amount is in Swiss Francs, in which case the period is used. Either an apostrophe or space is acceptable as the thousands separator."

List Separators

One of the side effects of internationalizing numbers and currencies is that changing grouping or fractional separators can collide with, and break, list (or other) processing. For example, if the program has a comma-separated list of prices and the fractional separator is changed to comma, the list will be incorrect. Similarly, a space-separated list can be broken when prices become represented with French grouping using the space character. When adding new types of separators, evaluate whether the new values can interfere with other parts of your application. You may want to insure that separators are not allowed to conflict. For example, if comma is used for a fractional separator, insure the list separator character is another value (e.g. semi-colon). Another solution, is to use an escape mechanism that allows a list or a string to represent syntax-significant characters (such as separators) within list items.

List Separator Examples
List TypeExampleNotes
Comma-separated list1.23,4.56,7.89Before, with full-stop fractional separator, 3 entries
Comma-separated list1,23,4,56,7,89After, with comma fractional separator, 6 entries
Space-separated list1,234 5,678 9,123Before, with comma grouping separator, 3 entries
Space-separated list1 234 5 678 9 123After, with space grouping separator, 6 entries
Single-quoted string'1,234 5,678 9,123'Before, with comma grouping separator, 3 entries
Single-quoted string'1'234 5'678 9'123'After, with quote grouping separator, 6 entries
Single-quoted string'1''234 5''678 9''123'After, with quote-escaped grouping separator, 3 entries
(2 quotes side-by-side represent an escaped single-quote character)

Currency Placement, Name, Symbol, Size, and 3-Letter ISO Codes

Note that in the above example of the former currency of Portugal, the symbol for Escudos, "ESC" comes after the amount. Currencies vary in placing the symbol in front of or behind the amount. The following example shows that even within a country the currency placement can vary.

Currency Placement Examples
Canadian French123,45 $Currency is a suffix
Canadian English$123.45Currency is a prefix
Canadian Inuktitut$123.45Currency in Nunavut is written same as English.

How many characters should you allow for currency symbol codes or names? There is an ISO standard, ISO 4217 that identifies 3-letter currency codes that can be used. Here is a (slightly outdated) list of the 3-letter currency codes.

The ISO codes are not the only abbreviations in use. The ISO 4217 code for Swiss Francs is CHF. But it is also common practice to use F, Fr. and SFr.

Users may not recognize abbreviations, so you may want to allow more characters and use a more descriptive name. To distinguish the "Denar" from the "Dinar", the "Mauritania Ouguiya" from the "Mauritius Rupee", or the "Guinea Franc" from the "Guinea-Bissau Peso", etc. you may want to have more than 5 characters. Some software applications allow for 15 characters in currency names.

Long text strings are good for specificity, but difficult for users to enter. Applications dealing with multiple currencies should consider a user interface design that simplifies currency selection. Especially where a few currencies are frequently used, 3-letter codes may be efficient, alongside a lookup for less frequently used codes.

Note that currency names as well as currency symbols may require localization.

Localized Currency Name Examples
EnglishSwiss franc
GermanSchweizer Franken
ItalianFranco svizzero
Localized currency names courtesy of Cloanto.

Information about the symbols represented by Unicode characters can be found in this Unicode Consortium chart for currency symbols. Unicode characters can be represented in HTML and XML by using the Unicode value between "&#x" and ";". For example, to represent the euro, whose Unicode value is U+20AC, write "&#x20AC;".

Currency Symbol Examples
CurrencyUnicode ValueNotes
dollar signU+0024$
pound signU+00A3£
yen signU+00A5¥
yen characterU+5186
euro signU+20AC
thai baht signU+0E3F฿
french franc signU+20A3
lira signU+20A4
korean won signU+20A9

Symbols in the notes column may not display properly, if an appropriate font is not available.


The number of digits after the fractional separator also varies. Some currencies, such as Japan, only use whole numbers and have no fractional components. Many currencies have 2 digits after the decimal point. Arabic countries (e.g. Bahrain, Egypt, Jordan, et al.) often have 3 digits of precision. Refer to this list of 3-letter currency codes as it also shows precision (see the column "minor units").

Number Width

Changing currency units can cause a significant change in the number field width. For example, something that costs $1 might convert to 1,000 Korean Won. When internationalizing applications, allow for expansion or resizing of currency data fields and for changes in precision. In some cases, the reduction in precision will help with the number width expansion, but you cannot rely on this.


Bear in mind, just as text is written with different characters around the word, so are numbers. You may need to display numbers using native digits, or perhaps receive data that uses these characters. One good thing, is that although Arabic is written right-to-left, numbers are written left-to-right. Hebrew uses the digits 0-9, left-to-right also. (Whew!). Look here for examples of european vs. arabic digits.

Fonts and Character Encodings

To use a character (such as a currency symbol) in a computer program or store it in a database, the character must be represented in the character encoding (code page) used by the program and database. For example, ISO 8859-1 does not have the euro symbol "€". It does have the Pound "£" and Yen "¥" symbols. If you want to represent different symbols be sure to choose an encoding that supports all of them. Unicode is always a good choice. If you are using markup languages such as HTML, XHTML, or XML, you can always represent any currency symbol, by using a Numeric Character Reference (NCR) and the symbol's Unicode value.

Of course, even if you can represent the character in your program, you will need a font that contains the symbol to be able to display it. Choose an appropriate font for the character encoding you use.
For information on different character encodings, see the I18n Guy web page on Character sets and code pages at the push of a button.
For information on converting a (Progress 4GL-based) application to Unicode, see Unicode-enabling Checklist for Progress Applications.

Formatting Euro Quantities

The move to the euro (€) has greatly simplified currency handling in Europe. However, one thing the move to the euro has not simplified is the formatting of euro quantities. Each country had its own style for formatting their old currency. There was reluctance to change to a new uniform style. So the specification for the euro doesn't prescribe how numbers should be formatted and so each country can continue to use its own style with the new euro currency. For example, group separator characters vary throughout Europe.

Which formats are used where?

I am often asked this and the intent behind the question is sometimes in reality a two-part question: Is the (pick one) example cited above correct? And, How does a software designer find out which formats are used in which countries?

Are the examples cited above correct?
Sometimes when I cite examples, such as the Swiss format choices, their correctness is challenged. I offer the examples as representative of how currencies can be different, so that designers of internationalized software can build into their software appropriate flexibility. The details of which forms are used in which market are unimportant to this paper.

The sources of these particular examples include various references, anecdotal sources, and my own experience. Although I believe they are all true, they may be dated, application-specific, not the most common usage, or may apply in a region of a country not the entire country, and I won't rule out urban legend.

How does a software designer find out which formats are used in which countries?
If you are designing software for Switzerland, France or any other market mentioned here, you should research the current requirements for that market, including user preferences, application requirements, government regulations, etc. There are several books on software internationalization that list formats used in different countries. Also, many software vendors, especially the operating system vendors, also document this information and provide API or system (and soon, internet) services that provide this information. They are generally reliable, but caveat emptor and make sure your application doesn't have special or different requirements.

When you research number and currency formats, you may want to look for the term locale. In software, locale refers to the collection of culture-specific information that varies by language or territory. It can include number and currency formats, and may also include date, time, and other formats and characteristics. There have been several attempts to register or catalog this kind of data. Currently, (2003) there is an effort to document these formats into XML-based documents for ease of interchange. Here is the XML Locale Data Repository, which will hopefully become a useful resource for all of us. (But remember the caveat above.)

Another resource for locale and/or software vendor information is I18nGuy's Information Resources For Locales And Internationalization (I18N) page.

If you need assistance, contact Xencraft.


I welcome your comments, especially interesting and unusual examples to supplement the above, constructive suggestions, critical remarks, and wisecracks. Send them to: XenCraft.