我有一台英语笔记本电脑,我的同事有一台德语笔记本电脑。我有一个单元测试如下:
@Test
public void myTest() {
String randomValue = roundFloat(4, 0.32258437873357226);
Assert.assertEquals(Double.parseDouble(randomValue), 0.3225);
}
public String roundFloat(int decimalDigits, Number randomValue) {
String formatPattern = getFormatPattern(decimalDigits);
DecimalFormat decimalFormat = new DecimalFormat(formatPattern);
decimalFormat.setRoundingMode(RoundingMode.FLOOR);
return decimalFormat.format(randomValue);
}
英语中的默认十进制分隔符为.
,德语中为,
。因此,该测试在我的机器上运行良好,但当我的同事运行它时,它会抱怨:
java.lang.NumberFormatException: For input string: "0,3225"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at de.vwag.fda.common.MeteringUnitTest.roundFloatTest(MeteringUnitTest.java:174)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.testng.TestRunner.privateRun(TestRunner.java:794)
at org.testng.TestRunner.run(TestRunner.java:596)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
at org.testng.SuiteRunner.run(SuiteRunner.java:276)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
at org.testng.TestNG.runSuites(TestNG.java:1063)
at org.testng.TestNG.run(TestNG.java:1031)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:135)
at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.executeMulti(TestNGDirectoryTestSuite.java:193)
at org.apache.maven.surefire.testng.TestNGDirectoryTestSuite.execute(TestNGDirectoryTestSuite.java:94)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:146)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:377)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:138)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:465)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:451)
那么,我如何修改我的测试,以便在所有可能的本地设置中运行它呢?
来自DecimalFormat文档:
To obtain a NumberFormat for a specific locale, including the default locale, call one of NumberFormat's factory methods, such as getInstance(). In general, do not call the DecimalFormat constructors directly, since the NumberFormat factory methods may return subclasses other than DecimalFormat.
这意味着您可以使用它来获得具有自定义区域设置的数字格式化程序,并像在代码中那样设置舍入模式:
NumberFormat format = NumberFormat.getNumberInstance(Locale.GERMAN);
if(format instanceof DecimalFormat) {
((DecimalFormat) format).setRoundingMode(RoundingMode.FLOOR);
}
我只会使用具有适当语言环境的System.printf
。
System.out.printf(Locale.GERMAN, "%.3f%n", 123.723);
System.out.printf(Locale.ENGLISH, "%.3f%n", 123.723);
打印
123,723
123.723
但是格式化程序也接受Locale。所以,如果你想做货币,你可以打电话:
NumberFormat df = NumberFormat.getCurrencyInstance(Locale.ENGLISH);
您可以四舍五入到指定的位数,如下所示。
String randomValue = roundFloat(4, .32258437873357226, Locale.GERMAN);
System.out.println(randomValue);
randomValue = roundFloat(7,.32258437873357226, Locale.ENGLISH);
System.out.println(randomValue);
打印
0,3225
0.3225843
roundFloat方法
public static String roundFloat(int decimalDigits, Double randomValue, Locale locale) {
DecimalFormat df = (DecimalFormat)DecimalFormat.getInstance(locale);
df.setMaximumFractionDigits(decimalDigits);
df.setRoundingMode(RoundingMode.FLOOR);
return df.format(randomValue);
}