您好我想知道如何格式化BigDecimal,表示数字,百分比,金额,整数到Locales中的String,从String返回BigDecimal。我正在使用功能强大的DecimalFormat,但我不确定如何在默认用户区域设置中使用转换为精确类型。我第一次使用它:
DecimalFormat.getCurrencyInstance().format( obj );
DecimalFormat.getCurrencyInstance().parse( source );
但是,由于数量庞大,其歪曲了它们的价值。所以我找到了一些东西并得到了这个:
DecimalFormat decimalFormat = new DecimalFormat();
decimalFormat.setParseBigDecimal( true );
BigDecimal bd = ( BigDecimal ) decimalFormat.parse( value );
但如何结合这些思考。我可能需要设置DecimalFormat一些在NumberFormat.get ??? instance()中使用的模式,但我不知道如何以及是否得到一些奇怪的行为。
那么请有经验的人帮助我吗?谢谢帕维尔
答案 0 :(得分:1)
我认为您最好的选择是假设getCurrencyInstace()
返回DecimalFormat
,它可能会在所有“重要”区域设置中返回instanceof
。为了安全起见,您可以使用public static BigDecimal parseCurrencyPrecise (String value)
{
NumberFormat format = NumberFormat.getCurrencyInstance ();
if (format instanceof DecimalFormat)
((DecimalFormat) format).setParseBigDecimal (true);
Number result = format.parse (value);
if (result instanceof BigDecimal)
return (BigDecimal) result;
else {
// Oh well...
return new BigDecimal (result.doubleValue ());
}
}
:
SimpleDateFormat
在我们的应用程序中,我们基本上会针对您需要DateFormat
的不同内容执行相同操作,但在一般情况下只有{{1}}。
答案 1 :(得分:0)
过了一会儿写了这个。它似乎有效,但我不确定它是否能在所有时间都正常工作。也许它可以帮助别人。我也希望它不违反任何许可证。)
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.Currency;
import java.util.Locale;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.UResourceBundle;
public class NumericHelper {
public static BigDecimal parseStringToBigDecimal( String value, DecimalFormat decimalFormat ) throws ParseException {
decimalFormat.setParseBigDecimal( true );
return ( BigDecimal ) decimalFormat.parse( value );
}
/**
* Extracted code from {@link NumberFormat#getPattern()} and
* {@link java.text.NumberFormat#getInstance(Locale desiredLocale, int choice)} with some
* modifications to get DecimalFormat with good Pattern
*
* @param choice is static values from class {@link NumberFormat} eg
* {@link NumberFormat#INTEGERSTYLE}
*/
public static DecimalFormat getDecimalFormatWithPattern( Locale desiredLocale, int choice ) {
ICUResourceBundle rb = ( ICUResourceBundle ) UResourceBundle.getBundleInstance( ICUResourceBundle.ICU_BASE_NAME, desiredLocale );
String[] numberPatterns = rb.getStringArray( "NumberPatterns" );
DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance( desiredLocale );
int entry = ( choice == NumberFormat.INTEGERSTYLE ) ? NumberFormat.NUMBERSTYLE : choice;
DecimalFormat format = new DecimalFormat( numberPatterns[entry], symbols );
if ( choice == NumberFormat.INTEGERSTYLE ) {
format.setMaximumFractionDigits( 0 );
format.setDecimalSeparatorAlwaysShown( false );
format.setParseIntegerOnly( true );
}
else if ( choice == NumberFormat.CURRENCYSTYLE ) {
adjustForCurrencyDefaultFractionDigits( format );
}
return format;
}
/**
* Extracted from {@link DecimalFormat#adjustForCurrencyDefaultFractionDigits()} because it can
* not be called
*/
protected static void adjustForCurrencyDefaultFractionDigits( DecimalFormat decimalFormat ) {
DecimalFormatSymbols symbols = decimalFormat.getDecimalFormatSymbols();
Currency currency = symbols.getCurrency();
if ( currency == null ) {
try {
currency = Currency.getInstance( symbols.getInternationalCurrencySymbol() );
}
catch ( IllegalArgumentException e ) {
}
}
if ( currency != null ) {
int digits = currency.getDefaultFractionDigits();
if ( digits != -1 ) {
int oldMinDigits = decimalFormat.getMinimumFractionDigits();
// Common patterns are "#.##", "#.00", "#".
// Try to adjust all of them in a reasonable way.
if ( oldMinDigits == decimalFormat.getMaximumFractionDigits() ) {
decimalFormat.setMinimumFractionDigits( digits );
decimalFormat.setMaximumFractionDigits( digits );
}
else {
decimalFormat.setMinimumFractionDigits( Math.min( digits, oldMinDigits ) );
decimalFormat.setMaximumFractionDigits( digits );
}
}
}
}
}
在接下来的一段时间之后我想到了 NumberFormat.get *** Instance()方法,它返回它的后代类( DecimalFormat ) 。我不确定这是如何工作的,但它确实有效。在代码中是时刻,试图从LocaleServiceProviderPool获取格式,所以我相信它也会返回DecimalFormat,如果有的话,那没问题使用这个原始方法并转换为DecimalFormat但是如果不是,你必须检查。在代码中我写的是这部分省略