com.ibm.icu.text.CurrencyMetaInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of icu4j Show documentation
Show all versions of icu4j Show documentation
International Component for Unicode for Java (ICU4J) is a mature, widely used Java library
providing Unicode and Globalization support
/*
*******************************************************************************
* Copyright (C) 2009-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.text;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
/**
* Provides information about currencies that is not specific to a locale.
*
* A note about currency dates. The CLDR data provides data to the day,
* inclusive. The date information used by CurrencyInfo and CurrencyFilter
* is represented by milliseconds, which is overly precise. These times are
* in GMT, so queries involving dates should use GMT times, but more generally
* you should avoid relying on time of day in queries.
*
* This class is not intended for public subclassing.
*
* @stable ICU 4.4
*/
public class CurrencyMetaInfo {
private static final CurrencyMetaInfo impl;
private static final boolean hasData;
/**
* Returns the unique instance of the currency meta info.
* @return the meta info
* @stable ICU 4.4
*/
public static CurrencyMetaInfo getInstance() {
return impl;
}
/**
* Returns the unique instance of the currency meta info, or null if
* noSubstitute is true and there is no data to support this API.
* @param noSubstitute true if no substitute data should be used
* @return the meta info, or null
* @stable ICU 49
*/
public static CurrencyMetaInfo getInstance(boolean noSubstitute) {
return hasData ? impl : null;
}
/**
* Returns true if there is data for the currency meta info.
* @return true if there is actual data
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public static boolean hasData() {
return hasData;
}
/**
* Subclass constructor.
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
protected CurrencyMetaInfo() {
}
/**
* A filter used to select which currency info is returned.
* @stable ICU 4.4
*/
public static final class CurrencyFilter {
/**
* The region to filter on. If null, accepts any region.
* @stable ICU 4.4
*/
public final String region;
/**
* The currency to filter on. If null, accepts any currency.
* @stable ICU 4.4
*/
public final String currency;
/**
* The from date to filter on (as milliseconds). Accepts any currency on or after this date.
* @stable ICU 4.4
*/
public final long from;
/**
* The to date to filter on (as milliseconds). Accepts any currency on or before this date.
* @stable ICU 4.4
*/
public final long to;
/**
* true if we are filtering only for currencies used as legal tender.
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public final boolean tenderOnly;
private CurrencyFilter(String region, String currency, long from, long to, boolean tenderOnly) {
this.region = region;
this.currency = currency;
this.from = from;
this.to = to;
this.tenderOnly = tenderOnly;
}
private static final CurrencyFilter ALL = new CurrencyFilter(
null, null, Long.MIN_VALUE, Long.MAX_VALUE, false);
/**
* Returns a filter that accepts all currency data.
* @return a filter
* @stable ICU 4.4
*/
public static CurrencyFilter all() {
return ALL;
}
/**
* Returns a filter that accepts all currencies in use as of the current date.
* @return a filter
* @see #withDate(Date)
* @stable ICU 4.4
*/
public static CurrencyFilter now() {
return ALL.withDate(new Date());
}
/**
* Returns a filter that accepts all currencies ever used in the given region.
* @param region the region code
* @return a filter
* @see #withRegion(String)
* @stable ICU 4.4
*/
public static CurrencyFilter onRegion(String region) {
return ALL.withRegion(region);
}
/**
* Returns a filter that accepts the given currency.
* @param currency the currency code
* @return a filter
* @see #withCurrency(String)
* @stable ICU 4.4
*/
public static CurrencyFilter onCurrency(String currency) {
return ALL.withCurrency(currency);
}
/**
* Returns a filter that accepts all currencies in use on the given date.
* @param date the date
* @return a filter
* @see #withDate(Date)
* @stable ICU 4.4
*/
public static CurrencyFilter onDate(Date date) {
return ALL.withDate(date);
}
/**
* Returns a filter that accepts all currencies that were in use at some point between
* the given dates, or if dates are equal, currencies in use on that date.
* @param from date on or after a currency must have been in use
* @param to date on or before which a currency must have been in use,
* or if equal to from, the date on which a currency must have been in use
* @return a filter
* @see #withDateRange(Date, Date)
* @stable ICU 49
*/
public static CurrencyFilter onDateRange(Date from, Date to) {
return ALL.withDateRange(from, to);
}
/**
* Returns a filter that accepts all currencies in use on the given date.
* @param date the date as milliseconds after Jan 1, 1970
* @stable ICU 51
*/
public static CurrencyFilter onDate(long date) {
return ALL.withDate(date);
}
/**
* Returns a filter that accepts all currencies that were in use at some
* point between the given dates, or if dates are equal, currencies in
* use on that date.
* @param from The date on or after a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @param to The date on or before which a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @stable ICU 51
*/
public static CurrencyFilter onDateRange(long from, long to) {
return ALL.withDateRange(from, to);
}
/**
* Returns a CurrencyFilter for finding currencies that were either once used,
* are used, or will be used as tender.
* @stable ICU 51
*/
public static CurrencyFilter onTender() {
return ALL.withTender();
}
/**
* Returns a copy of this filter, with the specified region. Region can be null to
* indicate no filter on region.
* @param region the region code
* @return the filter
* @see #onRegion(String)
* @stable ICU 4.4
*/
public CurrencyFilter withRegion(String region) {
return new CurrencyFilter(region, this.currency, this.from, this.to, this.tenderOnly);
}
/**
* Returns a copy of this filter, with the specified currency. Currency can be null to
* indicate no filter on currency.
* @param currency the currency code
* @return the filter
* @see #onCurrency(String)
* @stable ICU 4.4
*/
public CurrencyFilter withCurrency(String currency) {
return new CurrencyFilter(this.region, currency, this.from, this.to, this.tenderOnly);
}
/**
* Returns a copy of this filter, with from and to set to the given date.
* @param date the date on which the currency must have been in use
* @return the filter
* @see #onDate(Date)
* @stable ICU 4.4
*/
public CurrencyFilter withDate(Date date) {
return new CurrencyFilter(this.region, this.currency, date.getTime(), date.getTime(), this.tenderOnly);
}
/**
* Returns a copy of this filter, with from and to set to the given dates.
* @param from date on or after which the currency must have been in use
* @param to date on or before which the currency must have been in use
* @return the filter
* @see #onDateRange(Date, Date)
* @stable ICU 49
*/
public CurrencyFilter withDateRange(Date from, Date to) {
long fromLong = from == null ? Long.MIN_VALUE : from.getTime();
long toLong = to == null ? Long.MAX_VALUE : to.getTime();
return new CurrencyFilter(this.region, this.currency, fromLong, toLong, this.tenderOnly);
}
/**
* Returns a copy of this filter that accepts all currencies in use on
* the given date.
* @param date the date as milliseconds after Jan 1, 1970
* @stable ICU 51
*/
public CurrencyFilter withDate(long date) {
return new CurrencyFilter(this.region, this.currency, date, date, this.tenderOnly);
}
/**
* Returns a copy of this filter that accepts all currencies that were
* in use at some point between the given dates, or if dates are equal,
* currencies in use on that date.
* @param from The date on or after a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @param to The date on or before which a currency must have been in use.
* Measured in milliseconds since Jan 1, 1970 GMT.
* @stable ICU 51
*/
public CurrencyFilter withDateRange(long from, long to) {
return new CurrencyFilter(this.region, this.currency, from, to, this.tenderOnly);
}
/**
* Returns a copy of this filter that filters for currencies that were
* either once used, are used, or will be used as tender.
* @stable ICU 51
*/
public CurrencyFilter withTender() {
return new CurrencyFilter(this.region, this.currency, this.from, this.to, true);
}
/**
* {@inheritDoc}
* @stable ICU 4.4
*/
@Override
public boolean equals(Object rhs) {
return rhs instanceof CurrencyFilter &&
equals((CurrencyFilter) rhs);
}
/**
* Type-safe override of {@link #equals(Object)}.
* @param rhs the currency filter to compare to
* @return true if the filters are equal
* @stable ICU 4.4
*/
public boolean equals(CurrencyFilter rhs) {
return this == rhs || (rhs != null &&
equals(this.region, rhs.region) &&
equals(this.currency, rhs.currency) &&
this.from == rhs.from &&
this.to == rhs.to &&
this.tenderOnly == rhs.tenderOnly);
}
/**
* {@inheritDoc}
* @stable ICU 4.4
*/
@Override
public int hashCode() {
int hc = 0;
if (region != null) {
hc = region.hashCode();
}
if (currency != null) {
hc = hc * 31 + currency.hashCode();
}
hc = hc * 31 + (int) from;
hc = hc * 31 + (int) (from >>> 32);
hc = hc * 31 + (int) to;
hc = hc * 31 + (int) (to >>> 32);
hc = hc * 31 + (tenderOnly ? 1 : 0);
return hc;
}
/**
* Returns a string representing the filter, for debugging.
* @return A string representing the filter.
* @stable ICU 4.4
*/
@Override
public String toString() {
return debugString(this);
}
private static boolean equals(String lhs, String rhs) {
return lhs == rhs || (lhs != null && lhs.equals(rhs));
}
}
/**
* Represents the raw information about fraction digits and rounding increment.
* @stable ICU 4.4
*/
public static final class CurrencyDigits {
/**
* Number of fraction digits used to display this currency.
* @stable ICU 49
*/
public final int fractionDigits;
/**
* Rounding increment used when displaying this currency.
* @stable ICU 49
*/
public final int roundingIncrement;
/**
* Constructor for CurrencyDigits.
* @param fractionDigits the fraction digits
* @param roundingIncrement the rounding increment
* @stable ICU 4.4
*/
public CurrencyDigits(int fractionDigits, int roundingIncrement) {
this.fractionDigits = fractionDigits;
this.roundingIncrement = roundingIncrement;
}
/**
* Returns a string representing the currency digits, for debugging.
* @return A string representing the currency digits.
* @stable ICU 4.4
*/
@Override
public String toString() {
return debugString(this);
}
}
/**
* Represents a complete currency info record listing the region, currency, from and to dates,
* and priority.
* Use {@link CurrencyMetaInfo#currencyInfo(CurrencyFilter)}
* for a list of info objects matching the filter.
* @stable ICU 4.4
*/
public static final class CurrencyInfo {
/**
* Region code where currency is used.
* @stable ICU 4.4
*/
public final String region;
/**
* The three-letter ISO currency code.
* @stable ICU 4.4
*/
public final String code;
/**
* Date on which the currency was first officially used in the region.
* This is midnight at the start of the first day on which the currency was used, GMT.
* If there is no date, this is Long.MIN_VALUE;
* @stable ICU 4.4
*/
public final long from;
/**
* Date at which the currency stopped being officially used in the region.
* This is one millisecond before midnight at the end of the last day on which the currency was used, GMT.
* If there is no date, this is Long.MAX_VALUE.
*
* @stable ICU 4.4
*/
public final long to;
/**
* Preference order of currencies being used at the same time in the region. Lower
* values are preferred (generally, this is a transition from an older to a newer
* currency). Priorities within a single country are unique.
* @stable ICU 49
*/
public final int priority;
private final boolean tender;
/**
* @deprecated ICU 51 Use {@link CurrencyMetaInfo#currencyInfo(CurrencyFilter)} instead.
*/
@Deprecated
public CurrencyInfo(String region, String code, long from, long to, int priority) {
this(region, code, from, to, priority, true);
}
/**
* Constructs a currency info.
*
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
public CurrencyInfo(String region, String code, long from, long to, int priority, boolean tender) {
this.region = region;
this.code = code;
this.from = from;
this.to = to;
this.priority = priority;
this.tender = tender;
}
/**
* Returns a string representation of this object, useful for debugging.
* @return A string representation of this object.
* @stable ICU 4.4
*/
@Override
public String toString() {
return debugString(this);
}
/**
* Determine whether or not this currency was once used, is used,
* or will be used as tender in this region.
* @stable ICU 51
*/
public boolean isTender() {
return tender;
}
}
///CLOVER:OFF
/**
* Returns the list of CurrencyInfos matching the provided filter. Results
* are ordered by country code, then by highest to lowest priority (0 is highest).
* The returned list is unmodifiable.
* @param filter the filter to control which currency info to return
* @return the matching information
* @stable ICU 4.4
*/
public List currencyInfo(CurrencyFilter filter) {
return Collections.emptyList();
}
/**
* Returns the list of currency codes matching the provided filter.
* Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
* The returned list is unmodifiable.
* @param filter the filter to control which currencies to return. If filter is null,
* returns all currencies for which information is available.
* @return the matching currency codes
* @stable ICU 4.4
*/
public List currencies(CurrencyFilter filter) {
return Collections.emptyList();
}
/**
* Returns the list of region codes matching the provided filter.
* Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
* The returned list is unmodifiable.
* @param filter the filter to control which regions to return. If filter is null,
* returns all regions for which information is available.
* @return the matching region codes
* @stable ICU 4.4
*/
public List regions(CurrencyFilter filter) {
return Collections.emptyList();
}
///CLOVER:ON
/**
* Returns the CurrencyDigits for the currency code.
* @param isoCode the currency code
* @return the CurrencyDigits
* @stable ICU 4.4
*/
public CurrencyDigits currencyDigits(String isoCode) {
return defaultDigits;
}
/**
* @internal
* @deprecated This API is ICU internal only.
*/
@Deprecated
protected static final CurrencyDigits defaultDigits = new CurrencyDigits(2, 0);
static {
CurrencyMetaInfo temp = null;
boolean tempHasData = false;
try {
Class> clzz = Class.forName("com.ibm.icu.impl.ICUCurrencyMetaInfo");
temp = (CurrencyMetaInfo) clzz.newInstance();
tempHasData = true;
} catch (Throwable t) {
temp = new CurrencyMetaInfo();
}
impl = temp;
hasData = tempHasData;
}
private static String dateString(long date) {
if (date == Long.MAX_VALUE || date == Long.MIN_VALUE) {
return null;
}
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeZone(TimeZone.getTimeZone("GMT"));
gc.setTimeInMillis(date);
return "" + gc.get(Calendar.YEAR) + '-' + (gc.get(Calendar.MONTH) + 1) + '-' +
gc.get(Calendar.DAY_OF_MONTH);
}
private static String debugString(Object o) {
StringBuilder sb = new StringBuilder();
try {
for (Field f : o.getClass().getFields()) {
Object v = f.get(o);
if (v != null) {
String s;
if (v instanceof Date) {
s = dateString(((Date)v).getTime());
} else if (v instanceof Long) {
s = dateString(((Long)v).longValue());
} else {
s = String.valueOf(v);
}
if (s == null) {
continue;
}
if (sb.length() > 0) {
sb.append(",");
}
sb.append(f.getName())
.append("='")
.append(s)
.append("'");
}
}
} catch (Throwable t) {
}
sb.insert(0, o.getClass().getSimpleName() + "(");
sb.append(")");
return sb.toString();
}
}