예제 #1
0
  public void test(TestHarness harness) {
    Currency currency;

    /* Set default Locale for the JVM */
    Locale.setDefault(TEST_LOCALE);
    /* Get an instance of the currency */
    currency = Currency.getInstance(TEST_LOCALE);
    /* Check for the correct currency code */
    harness.check(
        currency.getCurrencyCode(),
        ISO4217_CODE,
        "ISO 4217 currency code retrieval check (" + currency.getCurrencyCode() + ").");
    /* Check for the correct currency symbol */
    harness.check(
        currency.getSymbol(),
        CURRENCY_SYMBOL,
        "Currency symbol retrieval check (" + currency.getSymbol() + ").");
    /* Check for the correct fraction digits */
    harness.check(
        currency.getDefaultFractionDigits(),
        FRACTION_DIGITS,
        "Currency fraction digits retrieval check (" + currency.getDefaultFractionDigits() + ").");
    /* Check for the correct currency code from toString()*/
    harness.check(
        currency.toString(),
        ISO4217_CODE,
        "ISO 4217 currency code retrieval check (" + currency.toString() + ").");
  }
  /** @tests java.text.DecimalFormatSymbols#setInternationalCurrencySymbol(java.lang.String) */
  @TestTargetNew(
      level = TestLevel.COMPLETE,
      notes = "",
      method = "setInternationalCurrencySymbol",
      args = {java.lang.String.class})
  @KnownFailure("getCurrency() doesn't return null for bogus currency code.")
  public void test_setInternationalCurrencySymbolLjava_lang_String() {
    Locale locale = Locale.CANADA;
    DecimalFormatSymbols dfs =
        ((DecimalFormat) NumberFormat.getCurrencyInstance(locale)).getDecimalFormatSymbols();
    Currency currency = Currency.getInstance("JPY");
    dfs.setInternationalCurrencySymbol(currency.getCurrencyCode());

    assertTrue("Test1: Returned incorrect currency", currency == dfs.getCurrency());
    assertEquals(
        "Test1: Returned incorrect currency symbol",
        currency.getSymbol(locale),
        dfs.getCurrencySymbol());
    assertTrue(
        "Test1: Returned incorrect international currency symbol",
        currency.getCurrencyCode().equals(dfs.getInternationalCurrencySymbol()));

    String symbol = dfs.getCurrencySymbol();
    dfs.setInternationalCurrencySymbol("bogus");
    assertNull("Test2: Returned incorrect currency", dfs.getCurrency());
    assertTrue("Test2: Returned incorrect currency symbol", dfs.getCurrencySymbol().equals(symbol));
    assertEquals(
        "Test2: Returned incorrect international currency symbol",
        "bogus",
        dfs.getInternationalCurrencySymbol());
  }
예제 #3
0
  /**
   * Builds a new currency instance for this locale. All components of the given locale, other than
   * the country code, are ignored. The results of calling this method may vary over time, as the
   * currency associated with a particular country changes. For countries without a given currency
   * (e.g. Antarctica), the result is null.
   *
   * @param locale a <code>Locale</code> instance.
   * @return a new <code>Currency</code> instance.
   * @throws NullPointerException if the locale or its country code is null.
   * @throws IllegalArgumentException if the country of the given locale is not a supported ISO3166
   *     code.
   */
  public static Currency getInstance(Locale locale) {
    /**
     * The new instance must be the only available instance for the currency it supports. We ensure
     * this happens, while maintaining a suitable performance level, by creating the appropriate
     * object on the first call to this method, and returning the cached instance on later calls.
     */
    Currency newCurrency;

    String country = locale.getCountry();
    if (locale == null || country == null) {
      throw new NullPointerException("The locale or its country is null.");
    }
    /* Attempt to get the currency from the cache */
    String code = (String) countryMap.get(country);
    if (code == null) {
      /* Create the currency for this locale */
      newCurrency = new Currency(locale);
      /*
       * If the currency code is null, then creation failed
       * and we return null.
       */
      code = newCurrency.getCurrencyCode();
      if (code == null) {
        return null;
      } else {
        /* Cache it */
        countryMap.put(country, code);
        cache.put(code, newCurrency);
      }
    } else {
      newCurrency = (Currency) cache.get(code);
    }
    /* Return the instance */
    return newCurrency;
  }
예제 #4
0
 public static String a(double d1, Currency currency)
 {
     DecimalFormat decimalformat;
     String s;
     boolean flag;
     if (a(currency).equals(","))
     {
         decimalformat = (DecimalFormat)NumberFormat.getInstance(d);
     } else
     {
         decimalformat = (DecimalFormat)NumberFormat.getInstance(c);
     }
     s = "#######0";
     if (b.indexOf(currency.getCurrencyCode().toUpperCase(Locale.US)) == -1)
     {
         flag = true;
     } else
     {
         flag = false;
     }
     currency = s;
     if (flag)
     {
         currency = "#####0.00";
     }
     decimalformat.applyPattern(currency);
     return decimalformat.format(d1);
 }
예제 #5
0
 private static String a(Locale locale, double d1, Currency currency, boolean flag)
 {
     String s;
     String s1;
     StringBuilder stringbuilder;
     boolean flag1;
     if (a(locale, currency) == 0)
     {
         flag1 = true;
     } else
     {
         flag1 = false;
     }
     s = currency.getSymbol();
     s1 = currency.getCurrencyCode();
     try
     {
         stringbuilder = new StringBuilder();
     }
     // Misplaced declaration of an exception variable
     catch (Locale locale)
     {
         return "";
     }
     if (flag1) goto _L2; else goto _L1
  static {
    String[] ids = null;

    try {
      Set<String> set = new TreeSet<>();

      Locale[] locales = Locale.getAvailableLocales();

      for (int i = 0; i < locales.length; i++) {
        Locale locale = locales[i];

        if (locale.getCountry().length() == 2) {
          Currency currency = Currency.getInstance(locale);

          String currencyId = currency.getCurrencyCode();

          set.add(currencyId);
        }
      }

      ids = set.toArray(new String[set.size()]);
    } catch (Exception e) {
      ids = new String[] {"USD", "CAD", "EUR", "GBP", "JPY"};
    } finally {
      CURRENCY_IDS = ids;
    }
  }
  /** @tests java.text.DecimalFormatSymbols#setCurrency(java.util.Currency) */
  @TestTargetNew(
      level = TestLevel.COMPLETE,
      notes = "",
      method = "setCurrency",
      args = {java.util.Currency.class})
  public void test_setCurrencyLjava_util_Currency() {
    Locale locale = Locale.CANADA;
    DecimalFormatSymbols dfs =
        ((DecimalFormat) NumberFormat.getCurrencyInstance(locale)).getDecimalFormatSymbols();

    try {
      dfs.setCurrency(null);
      fail("Expected NullPointerException");
    } catch (NullPointerException e) {
    }

    Currency currency = Currency.getInstance("JPY");
    dfs.setCurrency(currency);

    assertTrue("Returned incorrect currency", currency == dfs.getCurrency());
    assertEquals(
        "Returned incorrect currency symbol", currency.getSymbol(locale), dfs.getCurrencySymbol());
    assertTrue(
        "Returned incorrect international currency symbol",
        currency.getCurrencyCode().equals(dfs.getInternationalCurrencySymbol()));
  }
예제 #8
0
파일: Currency.java 프로젝트: forexpert/FHY
 public static Currency fromJDKCurrency(java.util.Currency jdkCurrency) {
   for (Currency c1 : Currency.values()) {
     if (jdkCurrency.getCurrencyCode().equals(c1.toString())) {
       return c1;
     }
   }
   return null;
 }
 /**
  * Sets the currency of these DecimalFormatSymbols. This also sets the currency symbol attribute
  * to the currency's symbol in the DecimalFormatSymbols' locale, and the international currency
  * symbol attribute to the currency's ISO 4217 currency code.
  *
  * @param currency the new currency to be used
  * @exception NullPointerException if <code>currency</code> is null
  * @since 1.4
  * @see #setCurrencySymbol
  * @see #setInternationalCurrencySymbol
  */
 public void setCurrency(Currency currency) {
   if (currency == null) {
     throw new NullPointerException();
   }
   this.currency = currency;
   intlCurrencySymbol = currency.getCurrencyCode();
   currencySymbol = currency.getSymbol(locale);
 }
예제 #10
0
 public static CurrencyUnit of(Currency currency) {
   String key = ISO_NAMESPACE + ':' + currency.getCurrencyCode();
   CurrencyUnit cachedItem = CACHED.get(key);
   if (cachedItem == null) {
     cachedItem = new JDKCurrencyAdapter(currency);
     CACHED.put(key, cachedItem);
   }
   return cachedItem;
 }
  private void initBaseCurrency(SQLiteDatabase db) {
    Cursor currencyCursor;

    // currencies
    try {
      CurrencyService currencyService = new CurrencyService(getContext());
      Currency systemCurrency = currencyService.getSystemDefaultCurrency();
      if (systemCurrency == null) return;

      InfoService infoService = new InfoService(getContext());

      currencyCursor =
          db.rawQuery(
              "SELECT * FROM "
                  + infoService.repository.getSource()
                  + " WHERE "
                  + Info.INFONAME
                  + "=?",
              new String[] {InfoKeys.BASECURRENCYID});
      if (currencyCursor == null) return;

      boolean recordExists = currencyCursor.moveToFirst();
      int recordId = currencyCursor.getInt(currencyCursor.getColumnIndex(Info.INFOID));
      currencyCursor.close();

      // Use the system default currency.
      int currencyId =
          currencyService.loadCurrencyIdFromSymbolRaw(db, systemCurrency.getCurrencyCode());

      if (!recordExists && (currencyId != Constants.NOT_SET)) {
        long newId = infoService.insertRaw(db, InfoKeys.BASECURRENCYID, currencyId);
        if (newId <= 0) {
          ExceptionHandler handler = new ExceptionHandler(getContext(), this);
          handler.showMessage("error inserting base currency on init");
        }
      } else {
        // Update the (empty) record to the default currency.
        long updatedRecords =
            infoService.updateRaw(db, recordId, InfoKeys.BASECURRENCYID, currencyId);
        if (updatedRecords <= 0) {
          ExceptionHandler handler = new ExceptionHandler(getContext(), this);
          handler.showMessage("error updating base currency on init");
        }
      }

      // Can't use provider here as the database is not ready.
      //            int currencyId =
      // currencyService.loadCurrencyIdFromSymbol(systemCurrency.getCurrencyCode());
      //            String baseCurrencyId = infoService.getInfoValue(InfoService.BASECURRENCYID);
      //            if (!StringUtils.isEmpty(baseCurrencyId)) return;
      //            infoService.setInfoValue(InfoService.BASECURRENCYID,
      // Integer.toString(currencyId));
    } catch (Exception e) {
      ExceptionHandler handler = new ExceptionHandler(getContext(), this);
      handler.handle(e, "init database, currency");
    }
  }
예제 #12
0
  /**
   * Returns a {@link String} instance representing the ISO 4217 code of the configuration
   * parameter's {@literal value}.
   *
   * @param value The configuration parameter's {@link Currency} value
   * @return A {@link String} instance representing the configuration parameter's typed value
   * @see java.util.Currency#getCurrencyCode()
   */
  @Override
  public String convertTo(Currency value) {

    if (value == null) {
      throw new ParameterException("Couldn't convert \"null\" to String.");
    }

    return value.getCurrencyCode();
  }
예제 #13
0
  @Override
  public boolean equals(Object object) {
    if (object == this) {
      return true;
    }
    if (!(object instanceof DecimalFormat)) {
      return false;
    }
    DecimalFormat obj = (DecimalFormat) object;

    if (obj.addr == this.addr) {
      return true;
    }

    boolean result = super.equals(object);

    result &= obj.toPattern().equals(this.toPattern());
    result &= obj.isDecimalSeparatorAlwaysShown() == this.isDecimalSeparatorAlwaysShown();
    result &= obj.getGroupingSize() == this.getGroupingSize();
    result &= obj.getMultiplier() == this.getMultiplier();
    result &= obj.getNegativePrefix().equals(this.getNegativePrefix());
    result &= obj.getNegativeSuffix().equals(this.getNegativeSuffix());
    result &= obj.getPositivePrefix().equals(this.getPositivePrefix());
    result &= obj.getPositiveSuffix().equals(this.getPositiveSuffix());
    result &= obj.getMaximumIntegerDigits() == this.getMaximumIntegerDigits();
    result &= obj.getMaximumFractionDigits() == this.getMaximumFractionDigits();
    result &= obj.getMinimumIntegerDigits() == this.getMinimumIntegerDigits();
    result &= obj.getMinimumFractionDigits() == this.getMinimumFractionDigits();
    result &= obj.isGroupingUsed() == this.isGroupingUsed();
    Currency objCurr = obj.getCurrency();
    Currency thisCurr = this.getCurrency();
    if (objCurr != null) {
      result &= objCurr.getCurrencyCode().equals(thisCurr.getCurrencyCode());
      result &= objCurr.getSymbol().equals(thisCurr.getSymbol());
      result &= objCurr.getDefaultFractionDigits() == thisCurr.getDefaultFractionDigits();
    } else {
      result &= thisCurr == null;
    }
    result &= obj.getDecimalFormatSymbols().equals(this.getDecimalFormatSymbols());

    return result;
  }
  @Test
  public void testGetCurrentJavaCurrency() {
    final CurrencyModel currency1 = new CurrencyModel();
    currency1.setIsocode("USD");

    when(sessionService.getAttribute(I18NConstants.CURRENCY_SESSION_ATTR_KEY))
        .thenReturn(currency1);
    final Currency currentJavaCurrency = i18NService.getCurrentJavaCurrency();

    assertEquals(
        "Wrong current java currency isocode! Should be: '"
            + currency1.getIsocode()
            + "' but was: '"
            + currentJavaCurrency.getCurrencyCode()
            + "'.",
        currency1.getIsocode(),
        currentJavaCurrency.getCurrencyCode());

    verify(sessionService, times(1)).getAttribute(Mockito.anyString());
  }
  @Test
  public void testComputeBalance() {
    Transaction transaction = new Transaction("Compute");
    Money firstSplitAmount = new Money("4.99", DEFAULT_CURRENCY.getCurrencyCode());
    Split split = new Split(firstSplitAmount, alphaAccount.getUID());
    transaction.addSplit(split);
    Money secondSplitAmount = new Money("3.50", DEFAULT_CURRENCY.getCurrencyCode());
    split = new Split(secondSplitAmount, bravoAccount.getUID());
    transaction.addSplit(split);

    mTransactionsDbAdapter.addRecord(transaction);

    // balance is negated because the CASH account has inverse normal balance
    transaction = mTransactionsDbAdapter.getRecord(transaction.getUID());
    Money savedBalance = transaction.getBalance(alphaAccount.getUID());
    assertThat(savedBalance).isEqualTo(firstSplitAmount.negate());

    savedBalance = transaction.getBalance(bravoAccount.getUID());
    assertThat(savedBalance.getNumerator()).isEqualTo(secondSplitAmount.negate().getNumerator());
    assertThat(savedBalance.getCurrency()).isEqualTo(secondSplitAmount.getCurrency());
  }
예제 #16
0
 private void exportCommodity(XmlSerializer xmlSerializer, List<Currency> currencies)
     throws IOException {
   for (Currency currency : currencies) {
     xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY);
     xmlSerializer.attribute(null, GncXmlHelper.ATTR_KEY_VERSION, "2.0.0");
     xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_SPACE);
     xmlSerializer.text("ISO4217");
     xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_SPACE);
     xmlSerializer.startTag(null, GncXmlHelper.TAG_COMMODITY_ID);
     xmlSerializer.text(currency.getCurrencyCode());
     xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY_ID);
     xmlSerializer.endTag(null, GncXmlHelper.TAG_COMMODITY);
   }
 }
  private Set<Pair<String, String>> getStoreNameSupportedCurrencySet(
      final List<Long> storeUidPks, final String currencyCode) {
    final Set<Pair<String, String>> storeNameCurrencySet = new HashSet<Pair<String, String>>();

    final List<Store> stores =
        getPersistenceEngine()
            .retrieveByNamedQueryWithList("STORE_WITH_UIDS", PLACEHOLDER_FOR_LIST, storeUidPks);

    for (Store store : stores) {
      for (Currency currency : store.getSupportedCurrencies()) {
        if (currencyCode == null) {
          storeNameCurrencySet.add(
              new Pair<String, String>(store.getName(), currency.getCurrencyCode()));
        } else {
          if (currency.getCurrencyCode().equalsIgnoreCase(currencyCode)) {
            storeNameCurrencySet.add(
                new Pair<String, String>(store.getName(), currency.getCurrencyCode()));
          }
        }
      }
    }
    return storeNameCurrencySet;
  }
  private void save() {
    String title = getCalculationTitle();
    Currency currency = (Currency) currencyField.getSelectedItem();
    List<String> personNames = getPersonNames();

    DataBaseHelper dbHelper = new DataBaseHelper(this);
    CalculationDataSource dataSource = new CalculationDataSource(dbHelper);
    Calculation calculation =
        dataSource.createCalculation(title, currency.getCurrencyCode(), personNames);
    dbHelper.close();

    Intent intent = new Intent(this, ExpenseListActivity.class);
    intent.putExtra(ExpenseListActivity.PARAM_CALCULATION_ID, calculation.getId());
    startActivity(intent);
    finish();
  }
예제 #19
0
  /**
   * Logs a purchase event with Facebook, in the specified amount and with the specified currency.
   * Additional detail about the purchase can be passed in through the parameters bundle.
   *
   * @param purchaseAmount Amount of purchase, in the currency specified by the 'currency'
   *     parameter. This value will be rounded to the thousandths place (e.g., 12.34567 becomes
   *     12.346).
   * @param currency Currency used to specify the amount.
   * @param parameters Arbitrary additional information for describing this event. Should have no
   *     more than 10 entries, and keys should be mostly consistent from one purchase event to the
   *     next.
   */
  public void logPurchase(BigDecimal purchaseAmount, Currency currency, Bundle parameters) {

    if (purchaseAmount == null) {
      notifyDeveloperError("purchaseAmount cannot be null");
      return;
    } else if (currency == null) {
      notifyDeveloperError("currency cannot be null");
      return;
    }

    if (parameters == null) {
      parameters = new Bundle();
    }
    parameters.putString(EVENT_PARAMETER_CURRENCY, currency.getCurrencyCode());

    logEventNow(EVENT_NAME_LOG_MOBILE_PURCHASE, purchaseAmount.doubleValue(), parameters);
  }
예제 #20
0
  public void printAvailableLocales(OutputStream os) throws Exception {
    Locale[] locales = Locale.getAvailableLocales();

    String name = null, country = null, lang = null, currencySb = null;
    String countryCd = null, langCd = null, currencyCd = null;
    Currency currency = null;

    PrintWriter pw = null;

    try {
      pw = new PrintWriter(os, true);

      for (Locale locale : locales) {
        name = locale.getDisplayName();
        country = locale.getDisplayCountry();
        countryCd = locale.getISOCountries()[0];
        lang = locale.getDisplayLanguage();
        langCd = locale.getISOLanguages()[0];

        try {
          currency = Currency.getInstance(locale);
          currencySb = currency.getSymbol();
          currencyCd = currency.getCurrencyCode();
        } catch (IllegalArgumentException ex) {
          currencySb = "";
          currencyCd = "";
        }

        pw.print("name : " + name + ", ");
        pw.print("country : " + country + "(" + countryCd + "), ");
        pw.print("lang : " + lang + "(" + langCd + "), ");
        pw.println("currency : " + currencySb + "(" + currencyCd + ")");
      }
    } catch (Exception ex) {
      throw ex;
    } finally {
      if (pw != null && os != (OutputStream) (System.out)) pw.close();
    }
  }
예제 #21
0
  /**
   * Opening an XML file should set the default currency to that used by the most accounts in the
   * file
   */
  @Test
  public void importingXml_shouldSetDefaultCurrency() {
    GnuCashApplication.setDefaultCurrencyCode("JPY");

    assertThat(GnuCashApplication.getDefaultCurrencyCode()).isEqualTo("JPY");
    assertThat(Commodity.DEFAULT_COMMODITY).isEqualTo(Commodity.JPY);

    mAccountsDbAdapter.deleteAllRecords();
    loadDefaultAccounts();

    assertThat(GnuCashApplication.getDefaultCurrencyCode()).isNotEqualTo("JPY");

    Currency currency = Currency.getInstance(GnuCashApplication.getDefaultLocale());
    String expectedCode = currency.getCurrencyCode();
    Commodity expectedDefaultCommodity =
        CommoditiesDbAdapter.getInstance().getCommodity(expectedCode);

    assertThat(GnuCashApplication.getDefaultCurrencyCode()).isEqualTo(expectedCode);
    assertThat(Commodity.DEFAULT_COMMODITY).isEqualTo(expectedDefaultCommodity);

    System.out.println("Default currency is now: " + expectedCode);
  }
예제 #22
0
  /**
   * Builds the currency corresponding to the specified currency code.
   *
   * @param currencyCode a string representing a currency code.
   * @return a new <code>Currency</code> instance.
   * @throws NullPointerException if currencyCode is null.
   * @throws IllegalArgumentException if the supplied currency code is not a supported ISO 4217
   *     code.
   */
  public static Currency getInstance(String currencyCode) {
    Locale[] allLocales;

    /*
     * Throw a null pointer exception explicitly if currencyCode is null.
     * One is not thrown otherwise.  It results in an
     * IllegalArgumentException.
     */
    if (currencyCode == null) {
      throw new NullPointerException("The supplied currency code is null.");
    }
    /* Nasty special case to allow an erroneous currency... blame Sun */
    if (currencyCode.equals("XXX")) return new Currency("XXX");
    Currency newCurrency = (Currency) cache.get(currencyCode);
    if (newCurrency == null) {
      /* Get all locales */
      allLocales = Locale.getAvailableLocales();
      /* Loop through each locale, looking for the code */
      for (int i = 0; i < allLocales.length; i++) {
        try {
          Currency testCurrency = getInstance(allLocales[i]);
          if (testCurrency != null && testCurrency.getCurrencyCode().equals(currencyCode)) {
            return testCurrency;
          }
        } catch (IllegalArgumentException exception) {
          /* Ignore locales without valid countries */
        }
      }
      /*
       * If we get this far, the code is not supported by any of
       * our locales.
       */
      throw new IllegalArgumentException(
          "The currency code, " + currencyCode + ", is not supported.");
    } else {
      return newCurrency;
    }
  }
예제 #23
0
 /** Side-step Currency.getSymbol() only returning a symbol if given a matching locale. */
 private static String getRealSymbol(Currency c) {
   switch (c.getCurrencyCode()) {
     case "USD":
       return "$";
     case "AUD":
       return "AU$";
     case "CAD":
       return "CA$";
     case "NZD":
       return "NZ$";
     case "BRL":
       return "R$";
     case "EUR":
       return "€";
     case "GBP":
       return "£";
     case "SEK":
     case "DKK":
     case "NOK":
       return "kr";
     case "SGD":
       return "S$";
     case "HKD":
       return "HK$";
     case "INR":
       return "₹";
     case "JPY":
       return "¥";
     case "ZAR":
       return "R";
     case "CHF":
       return "CHF";
     default:
       return c.getSymbol();
   }
 }
예제 #24
0
 public void write(Kryo kryo, Output output, Currency object) {
   output.writeString(object == null ? null : object.getCurrencyCode());
 }
예제 #25
0
  static String describeLocale(String name) {
    final StringBuilder result = new StringBuilder();
    result.append("<html>");

    final Locale locale = localeByName(name);

    result.append("<p>");
    append(result, "Display Name", locale.getDisplayName());
    append(result, "Localized Display Name", locale.getDisplayName(locale));

    if (locale.getLanguage().length() > 0) {
      String iso3Language = "(not available)";
      try {
        iso3Language = locale.getISO3Language();
      } catch (MissingResourceException ignored) {
      }

      result.append("<p>");
      append(result, "Display Language", locale.getDisplayLanguage());
      append(result, "Localized Display Language", locale.getDisplayLanguage(locale));
      append(result, "2-Letter Language Code", locale.getLanguage());
      append(result, "3-Letter Language Code", iso3Language);
    }
    if (locale.getCountry().length() > 0) {
      String iso3Country = "(not available)";
      try {
        iso3Country = locale.getISO3Country();
      } catch (MissingResourceException ignored) {
      }

      result.append("<p>");
      append(result, "Display Country", locale.getDisplayCountry());
      append(result, "Localized Display Country", locale.getDisplayCountry(locale));
      append(result, "2-Letter Country Code", locale.getCountry());
      append(result, "3-Letter Country Code", iso3Country);
    }
    if (locale.getVariant().length() > 0) {
      result.append("<p>");
      append(result, "Display Variant", locale.getDisplayVariant());
      append(result, "Localized Display Variant", locale.getDisplayVariant(locale));
      append(result, "Variant Code", locale.getVariant());
    }

    result.append("<p><b>Number Formatting</b>");
    describeNumberFormat(result, "Decimal", NumberFormat.getInstance(locale), 1234.5, -1234.5);
    describeNumberFormat(result, "Integer", NumberFormat.getIntegerInstance(locale), 1234, -1234);
    describeNumberFormat(
        result, "Currency", NumberFormat.getCurrencyInstance(locale), 1234.5, -1234.5);
    describeNumberFormat(result, "Percent", NumberFormat.getPercentInstance(locale), 12.3);

    boolean hasLocaleData = hasLocaleData();

    if (!hasLocaleData) {
      result.append("<p><b>Decimal Format Symbols</b>");
      NumberFormat nf = NumberFormat.getInstance(locale);
      if (nf instanceof DecimalFormat) {
        describeDecimalFormatSymbols(result, ((DecimalFormat) nf).getDecimalFormatSymbols());
      } else {
        result.append("(Didn't expect " + nf.getClass() + ".)");
      }
    }

    Date now =
        new Date(); // FIXME: it might be more useful to always show a time in the afternoon, to
    // make 24-hour patterns more obvious.
    result.append("<p><b>Date/Time Formatting</b>");
    describeDateFormat(
        result, "Full Date", DateFormat.getDateInstance(DateFormat.FULL, locale), now);
    describeDateFormat(
        result, "Long Date", DateFormat.getDateInstance(DateFormat.LONG, locale), now);
    describeDateFormat(
        result, "Medium Date", DateFormat.getDateInstance(DateFormat.MEDIUM, locale), now);
    describeDateFormat(
        result, "Short Date", DateFormat.getDateInstance(DateFormat.SHORT, locale), now);
    result.append("<p>");
    describeDateFormat(
        result, "Full Time", DateFormat.getTimeInstance(DateFormat.FULL, locale), now);
    describeDateFormat(
        result, "Long Time", DateFormat.getTimeInstance(DateFormat.LONG, locale), now);
    describeDateFormat(
        result, "Medium Time", DateFormat.getTimeInstance(DateFormat.MEDIUM, locale), now);
    describeDateFormat(
        result, "Short Time", DateFormat.getTimeInstance(DateFormat.SHORT, locale), now);
    result.append("<p>");
    describeDateFormat(
        result,
        "Full Date/Time",
        DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale),
        now);
    describeDateFormat(
        result,
        "Long Date/Time",
        DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale),
        now);
    describeDateFormat(
        result,
        "Medium Date/Time",
        DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale),
        now);
    describeDateFormat(
        result,
        "Short Date/Time",
        DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale),
        now);

    if (!hasLocaleData) {
      result.append("<p><b>Date Format Symbols</b><p>");
      DateFormat edf = DateFormat.getDateInstance(DateFormat.FULL, Locale.US);
      DateFormatSymbols edfs = ((SimpleDateFormat) edf).getDateFormatSymbols();
      DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, locale);
      DateFormatSymbols dfs = ((SimpleDateFormat) df).getDateFormatSymbols();
      append(result, "Local Pattern Chars", dfs.getLocalPatternChars());
      append(result, "Am/pm", Arrays.toString(dfs.getAmPmStrings()));
      append(result, "Eras", Arrays.toString(dfs.getEras()));
      append(result, "Months", Arrays.toString(dfs.getMonths()));
      append(result, "Short Months", Arrays.toString(dfs.getShortMonths()));
      append(result, "Weekdays", Arrays.toString(dfs.getWeekdays()));
      append(result, "Short Weekdays", Arrays.toString(dfs.getShortWeekdays()));
    }

    result.append("<p><b>Calendar</b><p>");
    Calendar c = Calendar.getInstance(locale);
    int firstDayOfWeek = c.getFirstDayOfWeek();
    String firstDayOfWeekString = new DateFormatSymbols(locale).getWeekdays()[firstDayOfWeek];
    String englishFirstDayOfWeekString =
        new DateFormatSymbols(Locale.US).getWeekdays()[firstDayOfWeek];
    String firstDayOfWeekDetails = firstDayOfWeek + " '" + firstDayOfWeekString + "'";
    if (!englishFirstDayOfWeekString.equals(firstDayOfWeekString)) {
      firstDayOfWeekDetails += " (" + englishFirstDayOfWeekString + ")";
    }
    append(result, "First Day of the Week", firstDayOfWeekDetails);
    append(result, "Minimal Days in First Week", c.getMinimalDaysInFirstWeek());

    // If this locale specifies a country, check out the currency.
    // Languages don't have currencies; countries do.
    if (!locale.getCountry().equals("")) {
      result.append("<p><b>Currency</b><p>");
      try {
        Currency currency = Currency.getInstance(locale);
        append(result, "ISO 4217 Currency Code", currency.getCurrencyCode());
        append(
            result,
            "Currency Symbol",
            unicodeString(currency.getSymbol(locale)) + " (" + currency.getSymbol(Locale.US) + ")");
        append(result, "Default Fraction Digits", currency.getDefaultFractionDigits());
      } catch (IllegalArgumentException ex) {
        result.append(
            "<p>(This version of Android is unable to return a Currency for this Locale.)");
      }
    }

    result.append("<p><b>Data Availability</b><p>");
    appendAvailability(result, locale, "BreakIterator", BreakIterator.class);
    appendAvailability(result, locale, "Calendar", NumberFormat.class);
    appendAvailability(result, locale, "Collator", Collator.class);
    appendAvailability(result, locale, "DateFormat", DateFormat.class);
    appendAvailability(result, locale, "DateFormatSymbols", DateFormatSymbols.class);
    appendAvailability(result, locale, "DecimalFormatSymbols", DecimalFormatSymbols.class);
    appendAvailability(result, locale, "NumberFormat", NumberFormat.class);

    if (hasLocaleData) {
      result.append("<p><b>libcore.icu.LocaleData</b>");
      try {
        Object enUsData = getLocaleDataInstance(Locale.US);
        Object localeData = getLocaleDataInstance(locale);
        String[] previous;

        result.append("<p>");
        describeStringArray(result, "amPm", enUsData, localeData, null);
        describeStringArray(result, "eras", enUsData, localeData, null);

        result.append("<p>");
        previous = describeStringArray(result, "longMonthNames", enUsData, localeData, null);
        describeStringArray(result, "longStandAloneMonthNames", enUsData, localeData, previous);
        previous = describeStringArray(result, "shortMonthNames", enUsData, localeData, null);
        describeStringArray(result, "shortStandAloneMonthNames", enUsData, localeData, previous);
        previous = describeStringArray(result, "tinyMonthNames", enUsData, localeData, null);
        describeStringArray(result, "tinyStandAloneMonthNames", enUsData, localeData, previous);

        result.append("<p>");
        previous = describeStringArray(result, "longWeekdayNames", enUsData, localeData, null);
        describeStringArray(result, "longStandAloneWeekdayNames", enUsData, localeData, previous);
        previous = describeStringArray(result, "shortWeekdayNames", enUsData, localeData, null);
        describeStringArray(result, "shortStandAloneWeekdayNames", enUsData, localeData, previous);
        previous = describeStringArray(result, "tinyWeekdayNames", enUsData, localeData, null);
        describeStringArray(result, "tinyStandAloneWeekdayNames", enUsData, localeData, previous);

        result.append("<p>");
        describeString(result, "yesterday", enUsData, localeData);
        describeString(result, "today", enUsData, localeData);
        describeString(result, "tomorrow", enUsData, localeData);

        result.append("<p>");
        describeString(result, "timeFormat12", enUsData, localeData);
        describeString(result, "timeFormat24", enUsData, localeData);

        result.append("<p>");
        describeChar(result, "zeroDigit", enUsData, localeData);
        describeChar(result, "decimalSeparator", enUsData, localeData);
        describeChar(result, "groupingSeparator", enUsData, localeData);
        describeChar(result, "patternSeparator", enUsData, localeData);
        describeChar(result, "percent", enUsData, localeData);
        describeChar(result, "perMill", enUsData, localeData);
        describeChar(result, "monetarySeparator", enUsData, localeData);
        describeChar(result, "minusSign", enUsData, localeData);
        describeString(result, "exponentSeparator", enUsData, localeData);
        describeString(result, "infinity", enUsData, localeData);
        describeString(result, "NaN", enUsData, localeData);

      } catch (Exception ex) {
        result.append("(" + ex.getClass().getSimpleName() + " thrown: " + ex.getMessage() + ")");
        System.err.println(ex);
      }
    }

    return result.toString();
  }