Skip to content
Legacy currencies

Currency code changes and redenominations

Currencies get redenominated, replaced and withdrawn – and their ISO 4217 codes change with them. Here are the changes developers run into most, with verified dates and ratios, and a pattern for handling legacy codes.

Last updated: · fxapi team

Your database has a column called currency, and somewhere in it is HRK – a currency that no longer exists. Currency code changes happen every year: countries remove zeros after high inflation, launch new currencies or adopt the euro, and the ISO 4217 code changes with them. If your code treats currency lists as fixed, the next change will break a lookup, an invoice or a report.

A currency code change occurs when ISO 4217 assigns a new code because a currency is redenominated, replaced or withdrawn. In a redenomination, old units are swapped for new ones at a fixed ratio – for example 1,000 old Sierra Leonean leones (SLL) for 1 new leone (SLE). The old code remains valid for historical data.

Why currencies change codes

Type of changeWhat happensExample
RedenominationZeros removed; new unit = N old unitsBYR → BYN (10,000:1)
Replacement by a new currencyNew currency introduced, often at parANG → XCG (1:1)
Adoption of another currencyNational currency replaced at a fixed conversion rateHRK → EUR (7.53450:1)
Withdrawal / unificationOne of two parallel currencies removedCUC withdrawn in Cuba, 2021

The ISO 4217 maintenance agency, SIX, publishes each new code in List One and moves the old one to List Three (historic currencies). The old and new codes usually overlap for a transition period in which both are legal tender. For background on how the codes are built, see ISO 4217 currency codes.

Major code changes developers encounter

Dates and ratios as announced by the respective central banks, the ECB and ISO 4217 amendments.

Old codeNew codeCountry / areaEffectiveRatio (old units per new unit)
ZMKZMWZambia1 Jan 20131,000
LVLEURLatvia1 Jan 20140.702804
LTLEURLithuania1 Jan 20153.45280
BYRBYNBelarus1 Jul 201610,000
MROMRUMauritania1 Jan 201810
STDSTNSão Tomé and Príncipe1 Jan 20181,000
VEFVESVenezuela20 Aug 2018100,000
CUC(CUP)Cuba1 Jan 2021Withdrawn; holdings converted at 24 CUP per CUC
SLLSLESierra Leone1 Jul 20221,000
HRKEURCroatia1 Jan 20237.53450
ZWLZWGZimbabweApr 2024One-off conversion at 2,498.7242 ZWL per ZiG
ANGXCGCuraçao and Sint Maarten31 Mar 20251 (at par)

The euro conversion rates are the fixed rates published by the European Central Bank.

Notes on individual changes

  • Venezuela (VEF → VES, then VED). The sovereign bolívar replaced the bolívar fuerte on 20 August 2018 at 100,000:1. On 1 October 2021, six more zeros were removed (1,000,000:1) for the digital bolívar, which ISO 4217 lists as VED. Before comparing Venezuelan rates across October 2021, check how your data source labels and adjusts the series.
  • Mauritania and São Tomé (2018). Both introduced new notes and coins on 1 January 2018. In São Tomé, old and new notes circulated together until 30 June 2018.
  • Belarus (2016). Old and new rubles circulated in parallel from 1 July to 31 December 2016.
  • Cuba (2021). Monetary unification started on 1 January 2021 with an official rate of 24 CUP per US dollar. The convertible peso (CUC) stopped being accepted in shops from 1 July 2021, and banks exchanged remaining CUC until 30 December 2021. CUC was withdrawn, not redenominated, so there is no successor code – the Cuban peso (CUP) continues.
  • Sierra Leone (2022). New leones entered circulation on 1 July 2022; old and new notes circulated in parallel during a transition period that the Bank of Sierra Leone extended into 2023.
  • Zimbabwe (2024). The Reserve Bank of Zimbabwe launched the ZiG (Zimbabwe Gold) in April 2024 and converted Zimbabwe dollar balances at 2,498.7242 ZWL per ZiG. ISO 4217 added the code ZWG in June 2024, and ZWL was withdrawn on 1 September 2024. Unlike a redenomination, this was a new currency with a one-off conversion rate.
  • Curaçao and Sint Maarten (2025). The Caribbean guilder (XCG) replaced the Netherlands Antillean guilder (ANG) at par on 31 March 2025; ANG ceased to be legal tender on 1 July 2025. Both are pegged to the US dollar at 1.79 per USD.

Why legacy codes stay in historical data

A rate for LTL on 30 December 2014 is real, correct data – it is what Lithuanian businesses used that day. Removing it would break every system that needs to:

  • Reproduce old invoices and reports in their original currency.
  • Audit past transactions and the rates applied at the time – see accounting and financial reporting.
  • Build long time series that span a currency change, for example Croatian prices from 2010 to today.
  • Migrate ERP data without rewriting history – see ERP integration.

That is why fxapi keeps 11 legacy codes for history – BYR, CUC, HRK, LTL, LVL, MRO, SLL, STD, VEF, ZMK and ZWL – next to their successors, with daily historical exchange rates back to 1999-01-01. New codes such as VES, MRU, STN, SLE, ZWG and XCG are available as both base_currency and target. The authoritative list of what fxapi supports is /v1/currencies.

How to handle currency code changes in code

1. Never hard-code the currency list

Load supported codes from /v1/currencies (or the SIX list) at startup and cache them for a day. Reject unknown codes with a clear error instead of silently converting at 0 or 1.

2. Keep the original currency on every record

Store the amount and the currency code exactly as transacted (1500.00 HRK), plus the date. Convert for reporting in a separate column. Never overwrite the original.

3. Use the official ratio, not a market rate

To express a pre-2023 kuna amount in euros, divide by 7.53450. Don’t look up an “HRK→EUR exchange rate” for a date after the changeover – the official ratio is exact and legally defined.

4. Choose the code by date

For a transaction date, pick the code that was valid then: HRK before 1 January 2023, EUR from that date. Data entry screens and imports should validate the pair (code, date).

5. Round with the successor’s minor unit

After conversion, round to the new currency’s decimals. The currency rounding and precision guide covers the details.

Example: normalize legacy amounts in Python

A small mapping with exact Decimal ratios converts legacy amounts to their successor currency. Look up exchange rates with fxapi only after normalizing:

from decimal import Decimal, ROUND_HALF_UP

# code: (successor, old units, new units)  →  new = amount * new_units / old_units
LEGACY = {
    "HRK": ("EUR", Decimal("7.53450"), Decimal("1")),
    "LTL": ("EUR", Decimal("3.45280"), Decimal("1")),
    "LVL": ("EUR", Decimal("0.702804"), Decimal("1")),
    "BYR": ("BYN", Decimal("10000"), Decimal("1")),
    "MRO": ("MRU", Decimal("10"), Decimal("1")),
    "STD": ("STN", Decimal("1000"), Decimal("1")),
    "VEF": ("VES", Decimal("100000"), Decimal("1")),
    "SLL": ("SLE", Decimal("1000"), Decimal("1")),
    "ZMK": ("ZMW", Decimal("1000"), Decimal("1")),
    "CUC": ("CUP", Decimal("1"), Decimal("24")),
}

def normalize(amount: Decimal, code: str, places: int = 2) -> tuple[Decimal, str]:
    if code not in LEGACY:
        return amount, code
    successor, old_units, new_units = LEGACY[code]
    converted = amount * new_units / old_units
    return converted.quantize(Decimal(1).scaleb(-places), rounding=ROUND_HALF_UP), successor

print(normalize(Decimal("1500.00"), "HRK"))   # (Decimal('199.08'), 'EUR')
print(normalize(Decimal("250000"), "SLL"))    # (Decimal('250.00'), 'SLE')

To value a legacy amount in another currency on its original date, keep the legacy code and call /v1/historical:

curl -G "https://api.fxapi.com/v1/historical" \
  -d date=2014-12-30 \
  -d base_currency=LTL \
  -d currencies=USD,EUR \
  -H "apikey: $FXAPI_KEY"

Key takeaways

  • Currencies are redenominated, replaced and withdrawn regularly; ISO 4217 assigns new codes each time.
  • Keep legacy codes and their history – they are needed for audits, reports and long time series.
  • Convert old amounts with the official fixed ratio, choose codes by transaction date, and never hard-code the currency list.
  • Use historical exchange rates for the old code on old dates. For the basics of rate data, read what is an exchange rate API.

Want to try it? fxapi is a FX rates API that returns live and historical rates for 190+ currencies as JSON – free for up to 300 requests a month.

Frequently asked questions

Why do currency codes change?
A new ISO 4217 code is usually assigned when a currency is redenominated (zeros removed), replaced by a new currency, or replaced by another country’s currency such as the euro. The new code lets old and new units coexist without ambiguity.
What is a currency redenomination?
A redenomination replaces old currency units with new ones at a fixed ratio, typically by removing zeros. Sierra Leone, for example, replaced 1,000 old leones (SLL) with 1 new leone (SLE) in 2022.
Why does historical exchange rate data still contain old codes like HRK or VEF?
Because transactions, invoices and reports from before the change were denominated in those currencies. To reproduce or audit them, you need rates for the old code on the old dates.
Which legacy currency codes does fxapi support?
fxapi keeps 11 legacy codes for historical data: BYR, CUC, HRK, LTL, LVL, MRO, SLL, STD, VEF, ZMK and ZWL, alongside current codes such as VES, MRU, STN, SLE, ZWG and XCG.
How should I convert an old-currency amount to the new currency?
For a redenomination or euro adoption, divide by the official fixed ratio (e.g., HRK ÷ 7.53450 = EUR). Don’t use a market exchange rate between the old and new codes – the official ratio is exact.
Free plan · no credit card

Get your free exchange rate API key

300 requests a month, latest and historical rates, fluctuation and averages – free forever. Upgrade when you need faster updates or more requests.