2015-12-08 21 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); 
    } 
} 

Output:Java Decimal vấn đề Format phân tích

Number Before parse: 1 201 

Number After parse: 1.0 

Dự kiến ​​Output:

Number Before parse: 1 201 

    Number After parse: **1201** 

bất kỳ có thể vui lòng giúp tôi hiểu tại sao phân tích không có khả năng chuyển đổi một locale PHÁP định dạng chuỗi (1 201) đến giá trị kép bình thường (1201.0)?

+0

tôi nhận thấy một cái gì đó giống như này Nếu tôi lần đầu tiên thử và định dạng một đôi như d này = 1201 Chuỗi retval = df.format (d); sau đó thử phân tích cú pháp giá trị được định dạng này sẽ là retVal = 1 201 double val = df.parse (retVal) .doubleValue(); điều này sẽ hoạt động và sẽ thấy val = 1201.0 Nhưng tôi đã có chuỗi ở định dạng FRENCH (1 201) và phân tích cú pháp trực tiếp không hoạt động. Không biết tại sao ... nếu bạn giúp tôi trả lời lý do. –

+0

Điều này có thể giúp: http://stackoverflow.com/a/8389625/3519951 –

+0

@AmitNag hãy xem câu trả lời của tôi ... Tôi giải thích rằng hành vi đó có – ParkerHalo

Trả lời

5

Có hai loại không gian. Ký tự khoảng trắng "bình thường" (số 32 - HEX 0x20) và khoảng trống không phá vỡ (NBSP) (Số 160 - HEX 0xA0).

Vì một lý do nào đó (tôi không biết tại sao) miền địa phương của Pháp kỳ vọng ký tự khoảng trắng giữa các chữ số là khoảng trắng không phá vỡ! Bạn có thể giúp mình với dòng mã này:

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

Bằng cách này mã của bạn sẽ hoạt động như mong đợi. Xin lưu ý rằng nếu bạn định dạng double thành một số String với ngôn ngữ Pháp thì ký tự khoảng trống kết quả sẽ là NBSP quá !!!

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

Quan sát tuyệt vời !!! +1 từ tôi. Nó cần một số gỡ lỗi quan tâm để hiểu điều này –

+0

Vâng điều này là khá hợp lý, vì bạn không muốn số của bạn để phá vỡ trên hai dòng chỉ vì có một không gian trong đó!(một số không có dấu cách sẽ không bị ngắt trừ khi nó chiếm toàn bộ dòng) –

+0

Cảm ơn bạn parker. Một nghi ngờ nữa là giải thích của bạn. Xin vui lòng cho tôi biết, nếu mã dưới đây sẽ giúp phân tích mà không thay đổi các đầu vào \t \t \t char groupingSep = (decimalFormat.getDecimalFormatSymbols()) getGroupingSeparator(). \t \t \t if (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

Bạn có thể sử dụng Output

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); 

dự kiến:

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

Chuỗi num = "1 201"; Đầu vào này có thể ở bất kỳ Định dạng địa phương nào như (1 201: 1,201 vv) Vì vậy, giải pháp đó là không thể trong trường hợp của tôi. Bất kỳ lý do gì về vấn đề này? –

3

Trên thực tế, Java đang sử dụng ký tự không thể phá vỡ không gian (\u00a0) để phân tích cú pháp số của Pháp.

Do đó, đoạn mã sau thực sự hoạt động:

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

Xem @ParkerHalo câu trả lời mà cung cấp thêm chi tiết.

+0

một quan sát thú vị của nó, tại sao một người nào đó sẽ downvote nó? có lẽ một bình luận làm thế nào để làm cho nó tốt hơn? – nafas

+0

mate để làm cho giải pháp của bạn là câu trả lời cho câu hỏi, chỉ cần lưu ý rằng '" "nên được thay thế bằng" \ u00a0 "' – nafas

1

Điều này dường như hoạt động.

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(); 
} 
Các vấn đề liên quan