2015-12-08 10 views
6
public class NumFormatTest 
{ 
    public static void main(String[] args) throws ParseException 
    { 
     String num = "1 201"; 
     DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRANCE); 
     System.out.println("Number Before parse: "+num);   
     double dm = df.parse(num).doubleValue(); 
     System.out.println("Number After parse: "+dm); 
    } 
} 

uscita:Java decimale problema Format analisi

Number Before parse: 1 201 

Number After parse: 1.0 

Output previsto:

Number Before parse: 1 201 

    Number After parse: **1201** 

Può qualcuno si prega di aiutarmi a capire il motivo per cui parse non è in grado di convertire un locale FRANCESE stringa formattata (1 201) al valore doppio normale (1201.0)?

+0

ho notato qualcosa di simile se prima provo e formattare una doppia come questo d = 1.201 String = retVal df.format (d); quindi prova ad analizzare questo valore formattato che sarebbe retVal = 1 201 double val = df.parse (retVal) .doubleValue(); questo funzionerebbe e vedrà val = 1201.0 Ma ho già una stringa in formato FRENCH (1 201) e l'analisi diretta non funziona. Non ho idea del perché ... se mi aiuti a rispondere alla ragione. –

+0

Questo può aiutare: http://stackoverflow.com/a/8389625/3519951 –

+0

@AmitNag dare un'occhiata alla mia risposta ... Sto spiegando che il comportamento ci – ParkerHalo

risposta

5

Ci sono due tipi di spazi. Il carattere di spazio "normale" (n. 32 - HEX 0x20) e lo spazio di non rottura (NBSP) (n. 160 - HEX 0xA0).

Per qualche motivo (non so perché) il locale francese si aspetta che il carattere di spazio bianco tra le cifre sia lo spazio non di rottura! È possibile aiutare se stessi con questa riga di codice:

String num = "1 201"; 
num = num.replaceAll(" ", "\u00A0"); // '\u00A0' is the non breaking whitespace character! 

In questo modo il codice funzionerà come previsto. Si noti che se si formatta uno double in un String con impostazioni locali francesi, il carattere dello spazio bianco risultante sarà anche l'NBSP !!!

DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRENCH); 
System.out.println(df.format(1201.1)); 
// This will print "1 202,1" But the space character will be '\u00A0'! 
+0

Grande osservazione !!! +1 da me. Ha bisogno di un po 'di debugging per capire questo –

+0

Beh, questo è abbastanza logico, dato che non vuoi che il tuo numero si spezzi su due linee solo perché c'è uno spazio in esso!(un numero senza spazi non sarebbe rotto a meno che non occupi l'intera linea) –

+0

Grazie Parker. Ancora un dubbio per la tua spiegazione. Per favore fatemi sapere, se il codice qui sotto vi aiuterà analizzare senza cambiare l'ingresso \t \t \t char groupingSep = (decimalFormat.getDecimalFormatSymbols()) getGroupingSeparator().; \t \t \t se (groupingSep == '\ u00A0') { \t \t \t \t groupingSep = ' '; \t \t \t \t DecimalFormatSymbols newSymbols = decimalFormat.getDecimalFormatSymbols(); \t \t \t \t newSymbols.setGroupingSeparator (groupingSep); \t \t \t \t decimalFormat.setDecimalFormatSymbols (newSymbols); \t \t \t} –

2

È possibile utilizzare l'uscita

String num = "1 201"; 
DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRANCE); 
System.out.println("Number Before parse: "+num); 

DecimalFormatSymbols symbols = df.getDecimalFormatSymbols(); 
symbols.setGroupingSeparator(' '); 
df.setDecimalFormatSymbols(symbols); 

double dm = df.parse(num).doubleValue(); 
System.out.println("Number After parse: "+dm); 

atteso:

Number Before parse: 1 201 
Number After parse: 1201.0 
+0

stringa num = "1 201"; Questo input può essere in qualsiasi formato locale come (1 201: 1,201 ecc.) Quindi la soluzione non è possibile nel mio caso. Qualsiasi motivo per cui questo problema? –

3

In realtà, Java sta usando lo spazio indistruttibile carattere (\u00a0) per analizzare i numeri francesi.

Così, il seguente codice funziona davvero:

String num = "1\u00a0201"; 
double dm = df.parse(num).doubleValue(); 
System.out.println("Number After parse: " + dm); 

See @ParkerHalo risposta che forniscono ulteriori dettagli.

+0

è un'osservazione interessante, perché qualcuno lo sottovaluterebbe? forse un commento su come renderlo migliore? – nafas

+0

per rendere la tua soluzione una risposta alla domanda, basta notare che "" "dovrebbe essere sostituito da" \ u00a0 "' – nafas

1

Questo sembra funzionare.

public double parse(String decimalAsText) { 
    NumberFormat decimalFormat = NumberFormat.getNumberInstance(Locale.FRANCE); 
    decimalAsText = decimalAsText.replace(' ', '\u00a0'); 
    ParsePosition pp = new ParsePosition(0); 
    Number n = decimalFormat.parse(decimalAsText, pp); 
    return n.doubleValue(); 
}