Currency Codes

ISO 4217 three-letter codes, symbols and regions for major currencies like CNY, USD, EUR, JPY and GBP.

How It Works

ISO 4217 identifies currencies with a three-letter code plus a three-digit number (USD, CNY, EUR, JPY), removing ambiguity where the same symbol or character names different currencies. Exchange rates float in the FX market, so a code's value changes over time.

Currency symbols (¥, $, €) are not unique — ¥ means both RMB and JPY, and $ is used by many countries. Machines and cross-border settlement therefore rely on ISO 4217 codes, not symbols; some currencies like JPY also have zero decimal places, a common localization trap.

When to Use This Table

This table is for converting amounts between currencies or confirming which code a symbol belongs to. The key point about ISO 4217 is that it defines currency codes and minor units, not exchange rates. Rates are time-varying market data entirely separate from the code table.

When not to consult it: you are doing amount calculation or conversion. Knowing CNY tells you nothing about which rate to use — that requires a live feed or periodic sync stored with a timestamp, otherwise historical orders cannot be recomputed.

Rule of thumb: use this table for codes, symbols and minor units; use a rate API for what 100 converts to today. Converting against a static rate table yields numbers that are simply wrong days later, and often wrong in ways that are hard to notice.

Mind minor units: JPY and KRW use zero decimals, CNY uses two, and BHD, KWD, JOD and TND use three. Applying a blanket two-decimal assumption across the table introduces systematic error, and the resulting amounts often still look plausible in accounting.

Boundaries and Common Pitfalls

  • A currency code is neither a country code nor a symbol

    Many countries share one currency (39 use EUR, USD is far more widespread) while one country may circulate several. Symbols are heavily ambiguous: $ can mean USD, CAD, AUD, HKD or dozens of others. Amounts must therefore be keyed by ISO code, with symbols for display only; any system keyed on the symbol will misreport as soon as a multi-currency report is produced.

  • Minor units and rounding rules must be explicit

    When rounding, you must fix both the step and the direction: rounding after conversion versus before can differ by a whole minor unit. Invoicing and accounting generally require rounding to the currency minor unit immediately after each operation, with the rounding mode (up, down, half-up, banker rounding) written into the contract, otherwise totals from different systems will not reconcile.

  • Historic and retired codes still circulate in data

    Retiring a code does not erase the data: old systems still carry CUC (Cuban convertible), VEB (Venezuelan bolívar) and pre-euro members like DEM and FRF. When handling historical financial records, external feeds or database migrations, recognise these codes and handle them by an explicit rule rather than discarding them as unknown, because dropping them silently breaks reconciliation.

How This Relates to Neighbours

For country and region identifiers (ISO 3166-1), use the in-site country-codes page; currency and country codes are related but independent and cannot be derived from one another.

For symbols, display names and rates, use a dedicated FX feed or currency API; this table provides codes and minor units only, never rates.

Amount formatting (symbol placement, thousands separators, minor units) is an i18n concern — use Intl.NumberFormat with the currency code instead of concatenating strings by hand.

For cross-border tax and compliance questions, this table provides no rules; consult each jurisdiction officially.

Practical Snippet

Key points: (1) hand amount formatting to Intl.NumberFormat, which derives minor units per currency (JPY 0, CNY 2, BHD 3) and handles symbol placement — manual concatenation always misses zero-decimal currencies; (2) rates must be stored alongside amounts with an asOf timestamp or historical orders cannot be recomputed; (3) round at each step with an explicit mode (half-up here), since rounding after conversion versus before can differ by a whole minor unit.

// 用 Intl.NumberFormat 处理金额,别手工拼符号
const amount = 1234567.891

// ① 按币种自动取小数位(JPY=0、CNY=2、BHD=3)与符号
new Intl.NumberFormat('zh-CN', {
  style: 'currency',
  currency: 'CNY',
}).format(amount)                        // ¥1,234,567.89

new Intl.NumberFormat('ja-JP', {
  style: 'currency',
  currency: 'JPY',
}).format(amount)                        // ¥1,234,568 —— 0 位小数自动生效

// ② 换算必须带时点,并把 timestamp 一起存,否则历史无法复算
type RateSnapshot = { base: string; rates: Record<string, number>; asOf: string }

async function convert(
  amount: number,
  from: string,
  to: string,
  snapshot: RateSnapshot,
): Promise<number> {
  if (from === to) return amount
  const rate = snapshot.rates[to] / snapshot.rates[from]
  const converted = amount * rate
  // 关键:按目标币种小数位舍入,用 half-up 避免银行家舍入带来的争议
  const dp = new Intl.NumberFormat('en', {
    style: 'currency',
    currency: to,
  }).resolvedOptions().maximumFractionDigits
  return Number(converted.toFixed(dp))
}

// ③ 恒定式金额只做展示换算,记账用原币种 + 快照汇率
// 存储:{ amount: 1234.56, currency: 'USD', rateToBase: 7.1234, asOf: '2026-01-15' }
// 展示时按 asOf 选快照,不按「今天的汇率」回算历史账目

Practical Notes

  • Money has no floating-point representation0.1 + 0.2 !== 0.3 is unacceptable for amounts. Store and compute in the minor unit (cents) as integers and format only at the edge; minor-unit digits are not always 2 (JPY has 0, dinar has 3), so hardcoding two decimals produces wrong totals.
  • Use ISO 4217 codes; currency symbols collide$ means USD, CAD, AUD and HKD, and ¥ means both CNY and JPY. Store codes (CNY/USD/JPY) in APIs and databases, and map to symbols only when rendering per locale, otherwise cross-currency operations mix accounts.
  • A converted amount needs a rate timestamp and a directionA rate is a ratio at a specific instant, and A→B differs from B→A by the spread. Finance requires recording the effective time and source; recomputing historical amounts with today rate will not reconcile.

Data Sources

  • ISO 4217 (currency codes and minor units)

Codes, names and definitions above come from public specifications; we claim no originality over the specification data itself. The arrangement, Chinese annotations and practical notes on this page are written by us.

CurrencyISO 4217SymbolRegion
Chinese YuanCNY¥China
Hong Kong DollarHKDHK$Hong Kong, China
Macanese PatacaMOPMOP$Macao, China
US DollarUSD$United States
EuroEUR€Eurozone
Japanese YenJPY¥Japan
Pound SterlingGBP£United Kingdom
South Korean WonKRW₩South Korea
Russian RubleRUB₽Russia
Canadian DollarCADC$Canada
Australian DollarAUDA$Australia
Swiss FrancCHFFrSwitzerland
Indian RupeeINR₹India
Brazilian RealBRLR$Brazil
Singapore DollarSGDS$Singapore

Frequently Asked Questions

How are the three letters of an ISO 4217 code determined?

Usually country code (2 letters) + currency initial: CN (China) + Y (Yuan) = CNY; in USD, US is the country and D stands for Dollar. Some are historical exceptions (e.g. GBP). The numeric code (e.g. 156 for CNY) is unrelated to the letters.

Both CNY and JPY use ¥ — how to tell them apart?

Yes, they share ¥. Disambiguate in writing by the ISO code: CNY (Chinese Yuan) vs JPY (Japanese Yen). In UI, show the code or a localized symbol (e.g. RMB for CNY, JP¥ for JPY) to avoid confusion.

Why do some currencies have no decimals (JPY, KRW)?

The smallest unit differs: JPY and KRW are counted in whole yen/won with no subunit, so 0 decimal places; CNY and USD have jiao/fen, so 2 decimals. ISO 4217 records this in the minor-unit field.

Does Bitcoin (BTC) have an ISO 4217 code?

No official ISO 4217 code. ISO reserves XBT as a non-official/experimental code (X prefix = non-country), but most exchanges still use BTC. Commodities like gold are also outside ISO 4217.