2013-03-23 10 views
5

Kullanıcının 45.60 (Amerikan Doları için örnek) gibi bir sayı girmesini sağlayan basit bir EditText var. dolayısıyla Locale.getDefault() ABD yerel dönmelidir (ve öyle) - Bazı para birimi dizeleri için NumberFormat.parse() başarısız oluyor

public String format() { 
    NumberFormat formatter = NumberFormat.getCurrencyInstance(Locale.getDefault()); 
    return formatter.format(amount.doubleValue()); 
} 

Ve Android telefonumda

, dil İngilizce (ABD) olarak ayarlanır: Sonra aşağıdaki yöntemi kullanarak bu sayıyı biçimlendirmek.

Şimdi düzenleme metni şu şekilde güncellenir: $45.60 (bu nedenle girilen numarayı biçimlendirmek çalışır).

Ben aşağıdaki yöntemi kullanarak yukarıdaki dize "$45.60" ayrıştırmak girişiminde Ancak eğer:

NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); 
Number result = numberFormat.parse("$45.60"); 

Bu başarısız: Ben bu "45.60" biçimlendirme, İngilizce/İngiltere'ye Telefonumu ayarlarsanız

java.lang.IllegalArgumentException: Failed to parse amount $45.60 using locale en_US. 

"£45.60" için doğru şekilde çalışıyor (ABD'de olduğu gibi), ancak yukarıdaki ABD örneğinde olduğu gibi "£45.60" ayrıştırılıyor.

Ancak, telefonumu Almanca (Almanya) olarak ayarlıyorum, "45,60" biçimlendirmesini "45,60€" doğru şekilde çalışıyor, VE ayrıştırma "45,60€" düzgün çalışıyor!

Bu üç para birimi arasında gördüğüm tek fark: Avro, miktara eklenirken, Dolar ve Pound miktara eklenir.

Herkesin bir fikri var, neden aynı kod Euro için çalışıyor, ancak Pound ve Dolar için değil? Bir şey mi eksik?

public void testCreateStringBased() throws Exception { 

    // For German locale 
    CurrencyAmount amount = new CurrencyAmount("25,46€", Locale.GERMANY); 
    assertEquals(25.46, amount.getAsDouble()); 

    // For French locale 
    amount = new CurrencyAmount("25,46€", Locale.FRANCE); 
    assertEquals(25.46, amount.getAsDouble()); 

    // For US locale 
    amount = new CurrencyAmount("$25.46", Locale.US); 
    assertEquals(25.46, amount.getAsDouble()); 

    // For UK locale 
    amount = new CurrencyAmount("£25.46", Locale.UK); 
    assertEquals(25.46, amount.getAsDouble()); 
} 

CurrencyAmount temelde ben o verilen yerel yerine varsayılan yerel alması haricinde, döviz dizeleri ayrıştırma için yayınlanan kod sarar:

Ben de sorunu yeniden oluşturma, bir birim testi yarattı. Yukarıdaki örnekte, test, ALMANYA ve Fransa yerel ayarları için başarılı olmakla birlikte, ABD ve İngiltere yerel ayarları için başarısızdır.

cevap

2

izleyerek görebilirsiniz sorunu tamamen çözmedi

diğer model sembolleri, ben acı amatörce bir yaklaşım aldı Şimdi sadece dize değerini para birimi sembolünden çıkarırım ... Bu şekilde istediğim her şeyi işleyebilirim: 45,78 veya 45,78 veya 45,78 veya 45,78 € ...

Girdi ne olursa olsun, para birimi sembolü basitçe sıyrılır ve ben de düz sayı ile bitirilir. Benim sertifikalarım şimdi (OP'ye bakınız) başarıyla tamamlandı.

Herhangi biri daha iyi bir şeyle gelirse, lütfen bana bildirin.

+0

Buna 'acımasızca amatörüm' demezdim. Özellikle EditText'in girdisini ayrıştırırken yaygın bir kullanım durumudur. Ayrıca doğrudan doğruya (w/para birimi) formatı doğrudan EditText'te (TextWatcher kullanarak) uygulamayı düşündüm, ancak bu çözümü kullanıcı için daha az müdahaleci olarak kullanıyorum. Teşekkürler. – pkk

1

NumberFormat.getInstance(). Parse() yerine NumberFormat.getCurrencyInstance(). Parse() öğesini deneyin. Aşağıdaki

+0

de kullanıcı görünüm başına kullanılıyor doğru Yerel Ayar sigorta gerekiyorsa aşağıda https://dzone.com/articles/currency-format-validation-and

import java.math.BigDecimal; import org.apache.commons.validator.routines.*; BigDecimalValidator currencyValidator = CurrencyValidator.getInstance(); BigDecimal parsedCurrency = currencyValidator.validate(currencyString); if (parsedCurrency == null) { throw new Exception("Invalid currency format (please also ensure it is UTF-8)"); } 

uyarlanan kullanıyorum ve gerçekten çalışmıyor. Aynı kodla 45.65 TL'nin yanı sıra 45.65'i de ayrıştırabilmem gerekiyor. Kodumu önerdiğiniz gibi değiştirirseniz, sayı dizelerini (para birimi Simgesi olmadan) ayrıştırmak artık işe yaramaz. Ve: bu değişikliklerden sonra 45.56 $ 'ı ayrıştırabilirim ama 45,56 € artık çalışmıyor oO ... – AgentKnopf

+1

Bu, Java ayrıştırma rutinlerinin bir sınırlamasıdır. Özel gereksinimleriniz için, ikisini de denemelisiniz. –

+1

Bu açıklama için teşekkürler. Ancak bu durumda, para birimi sembolünün basit bir şekilde değiştirilmesiyle daha iyi olacağımı düşünüyorum :) - çünkü bu, her dava için geçerli olan bir şey. Ve aynı şeyi yapmak için iki farklı yaklaşıma ihtiyacım varsa, biraz hantal, eğer bazı para birimlerinin para birimi sembolüne sahip olduğu için, diğer para birimi eklendiğinde: /. Mantıksal olarak basit olmalı: Her tür para birimi ayrıştırması için bir rutin. Yerel tabanlı olduğundan, bu sorun olmamalı, ama ne yazık ki bu kadar basit değil. – AgentKnopf

2

Dene:

NumberFormat numberFormat = new DecimalFormat("¤#.00", new DecimalFormatSymbols(Locale.UK)); 
numberFormat.parse("£123.5678"); 

¤ - para işareti, Yerel tarafından para birimi simgesiyle birlikte eşleşmeleri beklemektedir. Yani

String value = "$24,76" 
value = value.replace(getCurrencySymbol(locale), StringUtils.EMPTY); 

NumberFormat numberFormat = NumberFormat.getInstance(locale); 
Number result = numberFormat.parse(value); 

: Eğer bağlantıyı şimdiye kadar öne sürülmüştür cevapları yana http://docs.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html

+1

Öneriniz için teşekkürler, Dolar ve Pound için çalışıyor, ancak Euro için çalışmıyor. Şüpheliyim, çünkü Euro durumunda para birimi işareti eklenmiş değil, hazır değil mi? Ben evrensel olarak çalışan bir şey arıyorum. Gelebildiğim tek şey, para birimi sembolünü regex kullanarak çıkarır ve değeri ayrıştırır:/ama bunu önlemek isterim ... – AgentKnopf

+0

bir yaklaşım daha: Dize değeri = "123.5678 €" .replace (new DecimalFormatSymbols (Locale.GERMANY) .getCurrencySymbol(), ""); BigDecimal bigDecimal = new BigDecimal (value); – mokshino

+0

Şu anki para birimi simgesiyle ilgilenmiyor olmanıza yardımcı olur Hey, bu teklif için teşekkürler, bu, dün yayınladığım neredeyse bir şey;) (aşağıya kendi yanıtıma bakın) ve işte şu anda bunu yapıyorum. – AgentKnopf

0

Sen yerele farkında ayrıştırıcı sahip olmak için ayrıştırmak isteyen dize yerel bilmesi gerekir. GBP dizesi, NumberFormat'ın yerel ayarı en_GB olduğunda SADECE sayısal olarak ayrıştırılır; "Evrensel" ayrıştırıcı diye bir şey yoktur.

Örneğin, "12.000" dizgisi nasıl ayrıştırılır? En-us için, cevap on iki; de-de için, cevap on iki bin.

daima para miktarlarını ayrıştırmak için NumberFormat.getCurrencyInstance (java.util.Locale) kullanın.

İlgili konular