public static BigDecimal of(final BigDecimal amount, final Currency currency) { final CurrencyUnit currencyUnit = CurrencyUnit.getInstance(currency.toString()); return amount.setScale(currencyUnit.getDecimalPlaces(), ROUNDING_METHOD); } }
/** * Checks if this money has the scale of the currency. * <p> * Each currency has a default scale, such as 2 for USD and 0 for JPY. * This method checks if the current scale matches the default scale. * * @return true if the scale equals the current default scale */ public boolean isCurrencyScale() { return amount.scale() == currency.getDecimalPlaces(); }
/** * Returns a copy of this monetary value with the scale of the currency, * using the specified rounding mode if necessary. * <p> * The returned instance will have this currency and the new scaled amount. * For example, scaling 'USD 43.271' will yield 'USD 43.27' as USD has a scale of 2. * <p> * This instance is immutable and unaffected by this method. * * @param roundingMode the rounding mode to use, not null * @return the new instance with the input amount set, never null * @throws ArithmeticException if the rounding fails */ public BigMoney withCurrencyScale(RoundingMode roundingMode) { return withScale(currency.getDecimalPlaces(), roundingMode); }
/** * Gets the amount in minor units as a {@code BigDecimal} with scale 0. * <p> * This returns the monetary amount in terms of the minor units of the currency, * truncating the amount if necessary. * For example, 'EUR 2.35' will return 235, and 'BHD -1.345' will return -1345. * <p> * This is returned as a {@code BigDecimal} rather than a {@code BigInteger}. * This is to allow further calculations to be performed on the result. * Should you need a {@code BigInteger}, simply call {@link BigDecimal#toBigInteger()}. * * @return the minor units part of the amount, never null */ public BigDecimal getAmountMinor() { int cdp = getCurrencyUnit().getDecimalPlaces(); return amount.setScale(cdp, RoundingMode.DOWN).movePointRight(cdp); }
/** * Returns a copy of this monetary value with the scale of the currency, * truncating the amount if necessary. * <p> * The returned instance will have this currency and the new scaled amount. * For example, scaling 'USD 43.271' will yield 'USD 43.27' as USD has a scale of 2. * No rounding is performed on the amount, so it must have a * scale less than or equal to the new scale. * <p> * This instance is immutable and unaffected by this method. * * @return the new instance with the input amount set, never null * @throws ArithmeticException if the rounding fails */ public BigMoney withCurrencyScale() { return withScale(currency.getDecimalPlaces(), RoundingMode.UNNECESSARY); }
/** * Returns a copy of this monetary value with the amount in minor units added. * <p> * This adds the specified amount in minor units to this monetary amount, * returning a new object. * <p> * No precision is lost in the result. * The scale of the result will be the maximum of the current scale and the default currency scale. * For example, 'USD 23.45' plus '138' gives 'USD 24.83'. * <p> * This instance is immutable and unaffected by this method. * * @param amountToAdd the monetary value to add, not null * @return the new instance with the input amount added, never null */ public BigMoney plusMinor(long amountToAdd) { if (amountToAdd == 0) { return this; } BigDecimal newAmount = amount.add(BigDecimal.valueOf(amountToAdd, currency.getDecimalPlaces())); return BigMoney.of(currency, newAmount); }
/** * Returns a copy of this monetary value with the amount in minor units subtracted. * <p> * This subtracts the specified amount in minor units from this monetary amount, * returning a new object. * <p> * No precision is lost in the result. * The scale of the result will be the maximum of the current scale and the default currency scale. * For example, USD 23.45 minus '138' gives 'USD 22.07'. * <p> * This instance is immutable and unaffected by this method. * * @param amountToSubtract the monetary value to subtract, not null * @return the new instance with the input amount subtracted, never null */ public BigMoney minusMinor(long amountToSubtract) { if (amountToSubtract == 0) { return this; } BigDecimal newAmount = amount.subtract(BigDecimal.valueOf(amountToSubtract, currency.getDecimalPlaces())); return BigMoney.of(currency, newAmount); }
public static BigDecimal of(final BigDecimal amount, final Currency currency) { final CurrencyUnit currencyUnit = CurrencyUnit.getInstance(currency.toString()); return amount.setScale(currencyUnit.getDecimalPlaces(), BigDecimal.ROUND_HALF_UP); }
public static BigDecimal of(final BigDecimal amount, final Currency currency) { final CurrencyUnit currencyUnit = CurrencyUnit.getInstance(currency.toString()); return amount.setScale(currencyUnit.getDecimalPlaces(), ROUNDING_METHOD); } }
private CurrencyUnit readCurrency(ObjectInput in) throws IOException { String code = in.readUTF(); CurrencyUnit singletonCurrency = CurrencyUnit.of(code); if (singletonCurrency.getNumericCode() != in.readShort()) { throw new InvalidObjectException("Deserialization found a mismatch in the numeric code for currency " + code); } if (singletonCurrency.getDecimalPlaces() != in.readShort()) { throw new InvalidObjectException("Deserialization found a mismatch in the decimal places for currency " + code); } return singletonCurrency; }
/** * Obtains an instance of {@code Money} representing zero. * <p> * For example, {@code zero(USD)} creates the instance {@code USD 0.00}. * * @param currency the currency, not null * @return the instance representing zero, never null */ public static Money zero(CurrencyUnit currency) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); BigDecimal bd = BigDecimal.valueOf(0, currency.getDecimalPlaces()); return new Money(BigMoney.of(currency, bd)); }
/** * Obtains an instance of {@code BigMoney} from an amount in minor units. * <p> * This allows you to create an instance with a specific currency and amount * expressed in terms of the minor unit. * The scale of the money will be that of the currency, such as 2 for USD or 0 for JPY. * <p> * For example, if constructing US Dollars, the input to this method represents cents. * Note that when a currency has zero decimal places, the major and minor units are the same. * For example, {@code ofMinor(USD, 2595)} creates the instance {@code USD 25.95}. * * @param currency the currency, not null * @param amountMinor the amount of money in the minor division of the currency * @return the new instance, never null */ public static BigMoney ofMinor(CurrencyUnit currency, long amountMinor) { MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); return BigMoney.of(currency, BigDecimal.valueOf(amountMinor, currency.getDecimalPlaces())); }
/** * Gets the minor part of the amount. * <p> * This return the minor unit part of the monetary amount. * This is defined as the amount in minor units excluding major units. * <p> * For example, EUR has a scale of 2, so the minor part is always between 0 and 99 * for positive amounts, and 0 and -99 for negative amounts. * Thus 'EUR 2.35' will return 35, and 'EUR -1.34' will return -34. * * @return the minor part of the amount, negative if the amount is negative */ public int getMinorPart() { int cdp = getCurrencyUnit().getDecimalPlaces(); return amount.setScale(cdp, RoundingMode.DOWN) .remainder(BigDecimal.ONE) .movePointRight(cdp).intValueExact(); }
/** * Obtains an instance of {@code Money} from a {@code BigDecimal}. * <p> * This allows you to create an instance with a specific currency and amount. * No rounding is performed on the amount, so it must have a scale compatible * with the currency. * * @param currency the currency, not null * @param amount the amount of money, not null * @return the new instance, never null * @throws ArithmeticException if the scale exceeds the currency scale */ public static Money of(CurrencyUnit currency, BigDecimal amount) { MoneyUtils.checkNotNull(currency, "Currency must not be null"); MoneyUtils.checkNotNull(amount, "Amount must not be null"); if (amount.scale() > currency.getDecimalPlaces()) { throw new ArithmeticException("Scale of amount " + amount + " is greater than the scale of the currency " + currency); } return Money.of(currency, amount, RoundingMode.UNNECESSARY); }
@Override protected BigMoney fromConvertedColumns(Object[] convertedColumns) { CurrencyUnit currencyUnitPart = (CurrencyUnit) convertedColumns[0]; Long amountMajorPart = (Long) convertedColumns[1]; BigMoney theMoney = BigMoney.ofMajor(currencyUnitPart, amountMajorPart); if (theMoney.getScale() < currencyUnitPart.getDecimalPlaces()) { theMoney = theMoney.withCurrencyScale(); } return theMoney; }
@Override public BigMoney fromNonNullValue(Long value) { BigMoney theMoney = BigMoney.ofMajor(currencyUnit, value); if (theMoney.getScale() < currencyUnit.getDecimalPlaces()) { theMoney = theMoney.withCurrencyScale(); } return theMoney; }
@Override protected BigMoney fromConvertedColumns(Object[] convertedColumns) { CurrencyUnit currencyUnitPart = (CurrencyUnit) convertedColumns[0]; Long amountMajorPart = (Long) convertedColumns[1]; BigMoney theMoney = BigMoney.ofMajor(currencyUnitPart, amountMajorPart); if (theMoney.getScale() < currencyUnitPart.getDecimalPlaces()) { theMoney = theMoney.withCurrencyScale(); } return theMoney; }
private void writeCurrency(ObjectOutput out, CurrencyUnit obj) throws IOException { out.writeUTF(obj.getCode()); out.writeShort(obj.getNumericCode()); out.writeShort(obj.getDecimalPlaces()); }
/** * Obtains an instance of {@code Money} from a {@code BigDecimal}, rounding as necessary. * <p> * This allows you to create an instance with a specific currency and amount. * If the amount has a scale in excess of the scale of the currency then the excess * fractional digits are rounded using the rounding mode. * * @param currency the currency, not null * @param amount the amount of money, not null * @param roundingMode the rounding mode to use, not null * @return the new instance, never null * @throws ArithmeticException if the rounding fails */ public static Money of(CurrencyUnit currency, BigDecimal amount, RoundingMode roundingMode) { MoneyUtils.checkNotNull(currency, "CurrencyUnit must not be null"); MoneyUtils.checkNotNull(amount, "Amount must not be null"); MoneyUtils.checkNotNull(roundingMode, "RoundingMode must not be null"); amount = amount.setScale(currency.getDecimalPlaces(), roundingMode); return new Money(BigMoney.of(currency, amount)); }