DecimalFormat в зависимости от настроек системы?

У меня самая странная вещь с DecimalFormat.

Я использую его в веб-приложении. Я устанавливаю какой-то тест, и он продолжает терпеть неудачу со мной локально. Мой друг запустил его, и он смог успешно запустить тесты JUnit.

Странно то, что на нашем сервере приложение работает без проблем.

Может быть, Java зависит от системных настроек, таких как настройки Valueta и Number? Или может быть другая причина? Вот как выглядит мой кусок кода:

public String generateFormatPrice(double price) throws Exception {
    DecimalFormat format1 = new DecimalFormat("#,##0.00");
    String tmp = format1.format(price).replace(".", "&");
    String[] tmps = tmp.split("&");
    return tmps[0].replace(',', '.') + "," + tmps[1];
}

Заранее большое спасибо!


person Niels    schedule 05.01.2012    source источник
comment
Первое предложение Javadocs для DecimalFormat упоминание локали. Кроме того, где код для неудачного модульного теста?   -  person President James K. Polk    schedule 05.01.2012
comment
Вероятно, было бы неплохо указать, почему тесты терпят неудачу. Генерируется исключение? Если да, то какое исключение? Отличается ли результат от ожидаемого, что приводит к сбою утверждения JUnit? Если да, то какой результат вы получите и какой результат вы ожидаете?   -  person Alderath    schedule 05.01.2012
comment
Чтобы получить NumberFormat для определенной локали, включая локаль по умолчанию, вызовите один из фабричных методов NumberFormat, например getInstance(). Как правило, не вызывайте конструкторы DecimalFormat напрямую, поскольку фабричные методы NumberFormat могут возвращать подклассы, отличные от DecimalFormat. Если вам нужно настроить объект формата, сделайте что-то вроде этого: NumberFormat f = NumberFormat.getInstance(loc); если (f instanceof DecimalFormat) { ((DecimalFormat) f).setDecimalSeparatorAlwaysShown(true); }   -  person Viruzzo    schedule 05.01.2012


Ответы (1)


Этот код действительно зависит от локали. Если ваш код зависит от региона, например США, где "." — десятичный разделитель, а «,» — разделитель тысяч, а затем вы запустите этот код на сервере, настроенном, например, на немецкую локаль, произойдет сбой.

Рассмотрите возможность использования этого конструктор, который позволяет вам явно указать, какие символы вы используете.

РЕДАКТИРОВАТЬ: насколько я могу судить, вы пытаетесь форматировать числа, используя "." в качестве разделителя тысяч и "," в качестве десятичного разделителя. Другими словами, формат, используемый во Франции и Германии. Вот один из подходов, который позволит достичь этого:

public static String generateFormatPrice(double price) {
    final NumberFormat format = NumberFormat.getNumberInstance(Locale.GERMANY);
    format.setMinimumFractionDigits(2);
    format.setMaximumFractionDigits(2);
    return format.format(price);
}

Кроме того, вы не должны использовать двойное значение для хранения денежного значения - вы столкнетесь с некоторыми неприятными ошибками, если сделаете это.

person Steve McLeod    schedule 05.01.2012