1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.io.Serializable; 21162b0775772fa66b7eb634760a8159a60c1ddceaElliott Hughesimport libcore.icu.ICU; 22162b0775772fa66b7eb634760a8159a60c1ddceaElliott Hughesimport libcore.icu.LocaleData; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 250ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * A currency corresponding to an <a href="http://en.wikipedia.org/wiki/ISO_4217">ISO 4217</a> 2652b310afcffe8b6aed6fa0c1e9e8b0ade6f0a672Elliott Hughes * currency code such as "EUR" or "USD". 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic final class Currency implements Serializable { 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -158308464356906721L; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 310ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes private static final HashMap<String, Currency> codesToCurrencies = new HashMap<String, Currency>(); 320ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes private static final HashMap<Locale, Currency> localesToCurrencies = new HashMap<Locale, Currency>(); 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 342e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes private final String currencyCode; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Currency(String currencyCode) { 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project this.currencyCode = currencyCode; 380ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes String symbol = ICU.getCurrencySymbol(Locale.US.toString(), currencyCode); 39b0e5963793d8980b349f8e553067c19fd31601c5Elliott Hughes if (symbol == null) { 400ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes throw new IllegalArgumentException("Unsupported ISO 4217 currency code: " + 410ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes currencyCode); 422e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes } 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 460ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Returns the {@code Currency} instance for the given ISO 4217 currency code. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 480ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * if the currency code is not a supported ISO 4217 currency code. 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Currency getInstance(String currencyCode) { 510ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes synchronized (codesToCurrencies) { 520ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes Currency currency = codesToCurrencies.get(currencyCode); 530ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes if (currency == null) { 540ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes currency = new Currency(currencyCode); 550ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes codesToCurrencies.put(currencyCode, currency); 560ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 570ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return currency; 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the {@code Currency} instance for this {@code Locale}'s country. 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 640ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * if the locale's country is not a supported ISO 3166 country. 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static Currency getInstance(Locale locale) { 670ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes synchronized (localesToCurrencies) { 680ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes Currency currency = localesToCurrencies.get(locale); 690ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes if (currency != null) { 700ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return currency; 710ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 720ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes String country = locale.getCountry(); 730ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes String variant = locale.getVariant(); 740ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes if (!variant.isEmpty() && (variant.equals("EURO") || variant.equals("HK") || 750ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes variant.equals("PREEURO"))) { 760ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes country = country + "_" + variant; 770ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 780ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes 790ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes String currencyCode = ICU.getCurrencyCode(country); 800ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes if (currencyCode == null) { 810ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes throw new IllegalArgumentException("Unsupported ISO 3166 country: " + locale); 825b7b7fe6a817fdf058eefd9a716cc58a3283eb05claireho } else if (currencyCode.equals("XXX")) { 830ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return null; 840ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 850ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes Currency result = getInstance(currencyCode); 860ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes localesToCurrencies.put(locale, result); 870ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return result; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 890ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 910ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes /** 920ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Returns a set of all known currencies. 930ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * @since 1.7 940ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes */ 950ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes public static Set<Currency> getAvailableCurrencies() { 960ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes Set<Currency> result = new LinkedHashSet<Currency>(); 970ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes String[] currencyCodes = ICU.getAvailableCurrencyCodes(); 980ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes for (String currencyCode : currencyCodes) { 990ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes result.add(Currency.getInstance(currencyCode)); 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 10196474a05d47fcca92f7d511e41a20f994fc1e677Elliott Hughes return result; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1053106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * Returns this currency's ISO 4217 currency code. 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getCurrencyCode() { 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currencyCode; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1120ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Equivalent to {@code getDisplayName(Locale.getDefault())}. 1130ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 1140ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * @since 1.7 1150ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes */ 1160ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes public String getDisplayName() { 1170ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return getDisplayName(Locale.getDefault()); 1180ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 1190ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes 1200ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes /** 1210ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Returns the localized name of this currency in the given {@code locale}. 1220ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Returns the ISO 4217 currency code if no localized name is available. 1230ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * @since 1.7 1240ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes */ 1250ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes public String getDisplayName(Locale locale) { 1260ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return ICU.getCurrencyDisplayName(locale.toString(), currencyCode); 1270ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 1280ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes 1290ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes /** 1300ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Equivalent to {@code getSymbol(Locale.getDefault())}. 1313106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getSymbol() { 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getSymbol(Locale.getDefault()); 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1383106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * Returns the localized currency symbol for this currency in {@code locale}. 139aba52f92911e0faa4ae1907becc5a66cdb3254deElliott Hughes * That is, given "USD" and Locale.US, you'd get "$", but given "USD" and a non-US locale, 140aba52f92911e0faa4ae1907becc5a66cdb3254deElliott Hughes * you'd get "US$". 141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1423106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * <p>If the locale only specifies a language rather than a language and a country (such as 1433106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * {@code Locale.JAPANESE} or {new Locale("en", "")} rather than {@code Locale.JAPAN} or 1443106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * {new Locale("en", "US")}), the ISO 4217 currency code is returned. 1453106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * 1463106a99ccbe2e2a25bb66266d0ee42d98dd18099Elliott Hughes * <p>If there is no locale-specific currency symbol, the ISO 4217 currency code is returned. 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getSymbol(Locale locale) { 1492e3a41defb42a97b463194d859d2d4088a600fd8Elliott Hughes if (locale.getCountry().length() == 0) { 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currencyCode; 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 15333aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes // Check the locale first, in case the locale has the same currency. 154757a7942eed2b0aa457f8517a0259d2ac82c5b18Elliott Hughes LocaleData localeData = LocaleData.get(locale); 15533aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes if (localeData.internationalCurrencySymbol.equals(currencyCode)) { 15633aa6eb602478e7f51ac16f30c88db3566022886Elliott Hughes return localeData.currencySymbol; 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1592b1f1d31b83dbabc432a928bd30d443e01b16b46Elliott Hughes // Try ICU, and fall back to the currency code if ICU has nothing. 1600ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes String symbol = ICU.getCurrencySymbol(locale.toString(), currencyCode); 1612b1f1d31b83dbabc432a928bd30d443e01b16b46Elliott Hughes return symbol != null ? symbol : currencyCode; 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1650ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * Returns the default number of fraction digits for this currency. 1660ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * For instance, the default number of fraction digits for the US dollar is 2 because there are 1670ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * 100 US cents in a US dollar. For the Japanese Yen, the number is 0 because coins smaller 1680ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * than 1 Yen became invalid in 1953. In the case of pseudo-currencies, such as 1690ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes * IMF Special Drawing Rights, -1 is returned. 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getDefaultFractionDigits() { 1720ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes // In some places the code XXX is used as the fall back currency. 1730ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes // The RI returns -1, but ICU defaults to 2 for unknown currencies. 1740ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes if (currencyCode.equals("XXX")) { 1750ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return -1; 1760ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes } 1770ad1c14261c4db0731503770ec6a027e90cc6e38Elliott Hughes return ICU.getCurrencyFractionDigits(currencyCode); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns this currency's ISO 4217 currency code. 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currencyCode; 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Object readResolve() { 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getInstance(currencyCode); 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 192