วิธีการเปลี่ยนตัวแยกทศนิยมของ DecimalFormat จากเครื่องหมายจุลภาคเป็นจุด / จุด?


204

ฉันมีวิธีบ้าเล็กน้อยที่แปลงค่า BigDecimal เป็นสตริงที่ดีและอ่านได้

private String formatBigDecimal(BigDecimal bd){
    DecimalFormat df = new DecimalFormat();
    df.setMinimumFractionDigits(3);
    df.setMaximumFractionDigits(3);
    df.setMinimumIntegerDigits(1);
    df.setMaximumIntegerDigits(3);
    df.setGroupingSize(20);
    return df.format(bd);
}

อย่างไรก็ตามมันยังสร้างตัวคั่นการจัดกลุ่มที่เรียก","ว่าค่านิยมทั้งหมดของฉันออกมาเช่นนี้

xxx,xxx

ฉันต้องการให้ตัวคั่นเป็นจุดหรือจุดและไม่ใช่เครื่องหมายจุลภาค ใครบ้างมีเบาะแสของวิธีการบรรลุความสำเร็จเล็ก ๆ น้อย ๆ นี้?

ฉันได้อ่านนี้และโดยเฉพาะอย่างยิ่งนี้ไปสู่ความตายในขณะนี้ แต่ฉันไม่สามารถหาวิธีที่จะได้รับการกระทำเช่นนี้ ฉันกำลังเข้าใกล้สิ่งนี้ในทางที่ผิดหรือไม่? มีวิธีที่สง่างามกว่านี้อีกไหมในการทำเช่นนี้? อาจเป็นวิธีแก้ปัญหาที่ใช้แทนหมายเลขท้องถิ่นที่แตกต่างกันเนื่องจากเครื่องหมายจุลภาคจะสมบูรณ์แบบตามมาตรฐานยุโรป


คำตอบ:


323

คุณสามารถเปลี่ยนคั่นอย่างใดอย่างหนึ่งโดยการตั้งค่าสถานที่เกิดเหตุหรือการใช้DecimalFormatSymbols

หากคุณต้องการให้ตัวคั่นการจัดกลุ่มเป็นจุดคุณสามารถใช้โลแคลยุโรปได้:

NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;

อีกวิธีหนึ่งคุณสามารถใช้คลาส DecimalFormatSymbols เพื่อเปลี่ยนสัญลักษณ์ที่ปรากฏในตัวเลขที่จัดรูปแบบที่ผลิตโดยวิธีการจัดรูปแบบ สัญลักษณ์เหล่านี้รวมถึงตัวแยกทศนิยมตัวคั่นการจัดกลุ่มเครื่องหมายลบและเครื่องหมายเปอร์เซ็นต์และอื่น ๆ :

DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.'); 
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);

currentLocaleสามารถรับได้จาก Locale.getDefault () เช่น:

Locale currentLocale = Locale.getDefault();

1
คุณสามารถใช้ ApplyPattern ในรูปแบบทศนิยมเพื่อรับ. 00
krystan เพื่อเป็นเกียรติแก่

ฉันได้เปลี่ยน otherSymbols.setDecimalSeparator (','); เป็น otherSymbols.setDecimalSeparator ('.'); ขอบคุณ. มันใช้งานได้สำหรับฉัน
Aakanksha

2
เป็นรูปแบบที่มีลักษณะอย่างไรเช่นString formatString = "#,###,###,##0.00";ดูdocs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.htmlเพื่อหาไวยากรณ์
Vulpo

1
"คุณสามารถใช้ภาษายุโรป" คุณไม่สามารถใช้สถานที่จากยุโรปเพราะLocale.UKจะกลับมา1,567.90 และไม่ใช่ 1.567,90
JunjéJunhé

หมายเหตุด้านข้าง: NumberFormat.getNumberInstance()สามารถรันช้าลงอย่างผิดปกติในอุปกรณ์ Android 7 บางรุ่น อีกทางเลือกหนึ่งString.format()ที่ทำงานได้อย่างรวดเร็ว ดูstackoverflow.com/questions/2379221/java-currency-number-format
Mr-IDE

14

ยุโรปค่อนข้างใหญ่ ฉันไม่แน่ใจว่าพวกเขาใช้รูปแบบเดียวกันหมดหรือไม่ แต่นี้หรือนี้คำตอบที่จะได้รับการช่วยเหลือ

String text = "1,234567";
NumberFormat nf_in = NumberFormat.getNumberInstance(Locale.GERMANY);
double val = nf_in.parse(text).doubleValue();

NumberFormat nf_out = NumberFormat.getNumberInstance(Locale.UK);
nf_out.setMaximumFractionDigits(3);
String output = nf_out.format(val);

เช่นใช้สถานที่ที่ถูกต้อง


1
แน่นอนครับ! ในสหราชอาณาจักร "1,234.00 ปอนด์" จะเห็นได้ในขณะที่ในประเทศฝรั่งเศสคาดว่า "1 234,00 €" (ตัวคั่นกลุ่มตัวคั่นทศนิยมสัญลักษณ์สกุลเงินและสถานะสกุลเงินมีการเปลี่ยนแปลง)
Vulpo


5

BigDecimal ดูเหมือนจะไม่เคารพการตั้งค่าภาษา

Locale.getDefault(); //returns sl_SI

โลแคลสโลวีเนียควรมีเครื่องหมายจุลภาคทศนิยม ฉันคิดว่าฉันเข้าใจผิดเกี่ยวกับตัวเลข

a = new BigDecimal("1,2") //throws exception
a = new BigDecimal("1.2") //is ok

a.toPlainString() // returns "1.2" always

ฉันได้แก้ไขบางส่วนของข้อความที่ไม่สมเหตุสมผลเพราะมันพิสูจน์แล้วว่าเป็นเพราะความผิดพลาดของมนุษย์ (ลืมที่จะส่งข้อมูลและมองสิ่งผิด ๆ )

เช่นเดียวกับ BigDecimal สามารถพูดได้สำหรับฟังก์ชั่น Java .toString () ใด ๆ ฉันเดาว่าดีในบางวิธี การทำให้เป็นอนุกรมสำหรับตัวอย่างหรือการดีบัก มีการแทนค่าสตริงที่ไม่ซ้ำกัน

เช่นเดียวกับคนอื่น ๆ กล่าวถึงการใช้ตัวจัดรูปแบบทำงานได้ เพียงใช้ตัวจัดรูปแบบเช่นเดียวกับส่วนหน้าของ JSF ตัวจัดรูปแบบทำงานได้อย่างถูกต้องและตระหนักถึงโลแคล


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.