package ilarkesto.base;
import java.util.Locale;
import java.util.StringTokenizer;
/**
* Working with money (amount + currency).
*/
public final class Money implements Comparable<Money> {
public static void main(String[] args) {
System.out.println(new Money(12000000000d, USD).toString(Locale.GERMANY));
}
public static final transient String EUR = "EUR";
public static final transient String USD = "USD";
private long cent;
private String currency;
public Money(long value, long cent, String currency) {
this.cent = (value * 100) + cent;
this.currency = currency;
if (this.currency == null) throw new RuntimeException("currency == null");
}
public Money(String s) {
StringTokenizer tokenizer = new StringTokenizer(s, " ");
if (!tokenizer.hasMoreTokens()) throw new RuntimeException("Illegal money format: " + s);
String amount = tokenizer.nextToken();
this.cent = Math.round(Double.parseDouble(amount.replace(',', '.')) * 100);
if (!tokenizer.hasMoreTokens()) throw new RuntimeException("Illegal money format (missing currency): " + s);
this.currency = tokenizer.nextToken();
if (this.currency == null) throw new RuntimeException("currency == null");
}
public Money(String amount, String currency) {
this.cent = Math.round(Double.parseDouble(amount.replace(',', '.')) * 100);
this.currency = currency;
if (this.currency == null) throw new RuntimeException("currency == null");
}
public Money(double value, String currency) {
this.cent = Math.round(value * 100);
this.currency = currency;
if (this.currency == null) throw new RuntimeException("currency == null");
}
public String getCurrency() {
return currency;
}
public float getAmountAsFloat() {
return cent / 100f;
}
public double getAmountAsDouble() {
return cent / 100d;
}
public long getAmountAsCent() {
return cent;
}
public boolean isPositive() {
return cent >= 0;
}
public boolean isNegative() {
return cent < 0;
}
public Money negate() {
return new Money(0, cent * -1, currency);
}
public Money substract(Money money) {
if (money == null) return this;
if (!currency.equals(money.currency))
throw new RuntimeException("Cannot subtract " + money.currency + " from " + currency + ".");
return new Money(0, cent - money.cent, currency);
}
public Money add(Money money) {
if (money == null) return this;
if (!currency.equals(money.currency))
throw new RuntimeException("Cannot add " + money.currency + " to " + currency + ".");
return new Money(0, cent + money.cent, currency);
}
public Money invert() {
return new Money(0, cent * -1, currency);
}
public Money multiply(float factor) {
return new Money(0, Math.round((cent * factor)), currency);
}
public Money divide(float divisor) {
return new Money(0, Math.round((cent / divisor)), currency);
}
public String getAmountAsString(char decimalSeparator) {
return getAmountAsString(decimalSeparator, null);
}
public String getAmountAsString(char decimalSeparator, String thousandsSeparator) {
boolean neg = false;
long c = cent;
if (c < 0) {
neg = true;
c = Math.abs(c);
}
long value = c / 100;
long rest = c - (value * 100);
StringBuilder sb = new StringBuilder();
if (neg) sb.append("-");
sb.append(Str.formatWithThousandsSeparator(value, thousandsSeparator));
sb.append(decimalSeparator);
if (rest < 10) sb.append('0');
sb.append(rest);
return sb.toString();
}
public String toString(Locale locale) {
if (locale != null) {
if (locale.equals(Locale.GERMAN) || locale.equals(Locale.GERMANY))
return getAmountAsString(',', ".") + ' ' + currency;
}
return toString('.');
}
public String toString(char decimalSeparator) {
return getAmountAsString(decimalSeparator) + ' ' + currency;
}
public boolean isLessThen(Money m) {
return cent < m.cent;
}
public boolean isLessThenOrEqualTo(Money m) {
return cent <= m.cent;
}
public boolean isGreaterThen(Money m) {
return cent > m.cent;
}
public boolean isGreaterThenOrEqualTo(Money m) {
return cent >= m.cent;
}
@Override
public String toString() {
return toString(null);
}
@Override
public boolean equals(Object obj) {
if (obj == null) return false;
Money other = (Money) obj;
return cent == other.cent && currency.equals(other.currency);
}
private int hashCode;
@Override
public int hashCode() {
if (hashCode == 0) {
hashCode = 23;
hashCode = hashCode * 37 + (int) cent;
hashCode = hashCode * 37 + currency.hashCode();
}
return hashCode;
}
public int compareTo(Money o) {
if (cent > o.cent) return 1;
if (cent < o.cent) return -1;
return 0;
}
// --- ---
public static Money computeAvg(Money[] moneys, String currency) {
return computeSum(moneys, currency).divide(moneys.length);
}
public static Money computeSum(Money[] moneys, String currency) {
Money sum = new Money(0, currency);
for (Money money : moneys) {
sum = sum.add(money);
}
return sum;
}
public static Money[] createArray(int size, Money initialValue) {
Money[] moneys = new Money[size];
for (int i = 0; i < size; i++)
moneys[i] = initialValue;
return moneys;
}
}