ICU-8464 Update Java RelativeDateTimeFormatter with latest API proposal.

X-SVN-Rev: 34709
This commit is contained in:
Travis Keep 2013-12-04 21:19:34 +00:00
parent ef0debb8be
commit 3fa5329e97
2 changed files with 50 additions and 20 deletions

View File

@ -33,7 +33,7 @@ import com.ibm.icu.util.UResourceBundle;
* involving one single unit. This API does not support relative dates
* involving compound units.
* e.g "in 5 days and 4 hours" nor does it support parsing.
* This class is NOT thread-safe.
* This class is both immutable and thread-safe.
* <p>
* Here are some examples of use:
* <blockquote>
@ -277,6 +277,8 @@ public final class RelativeDateTimeFormatter {
/**
* Returns a RelativeDateTimeFormatter for a particular locale.
*
* @param locale the locale.
* @draft ICU 53
* @provisional
*/
@ -290,6 +292,25 @@ public final class RelativeDateTimeFormatter {
NumberFormat.getInstance(locale));
}
/**
* Returns a RelativeDateTimeFormatter for a particular locale that uses a particular
* NumberFormat object.
*
* @param locale the locale
* @param nf the number format object. It is defensively copied to ensure thread-safety
* and immutability of this class.
* @draft ICU 53
* @provisional
*/
public static RelativeDateTimeFormatter getInstance(ULocale locale, NumberFormat nf) {
RelativeDateTimeFormatterData data = cache.get(locale);
return new RelativeDateTimeFormatter(
data.qualitativeUnitMap,
data.quantitativeUnitMap,
new MessageFormat(data.dateTimePattern),
PluralRules.forLocale(locale),
(NumberFormat) nf.clone());
}
/**
* Formats a relative date with a quantity such as "in 5 days" or
@ -309,7 +330,13 @@ public final class RelativeDateTimeFormatter {
if (direction != Direction.LAST && direction != Direction.NEXT) {
throw new IllegalArgumentException("direction must be NEXT or LAST");
}
return getQuantity(unit, direction == Direction.NEXT).format(quantity, numberFormat, pluralRules);
// This class is thread-safe, yet numberFormat is not. To ensure thread-safety of this
// class we must guarantee that only one thread at a time uses our numberFormat.
synchronized (numberFormat) {
return getQuantity(
unit, direction == Direction.NEXT).format(
quantity, numberFormat, pluralRules);
}
}
/**
@ -330,21 +357,6 @@ public final class RelativeDateTimeFormatter {
}
return this.qualitativeUnitMap.get(unit).get(direction);
}
/**
* Specify which NumberFormat object this object should use for
* formatting numbers. By default this object uses the default
* NumberFormat object for this object's locale.
* @param nf the NumberFormat object to use. This method makes
* its own defensive copy of nf so that subsequent
* changes to nf will not affect the operation of this object.
* @see #format(double, Direction, RelativeUnit)
* @draft ICU 53
* @provisional
*/
public void setNumberFormat(NumberFormat nf) {
this.numberFormat = (NumberFormat) nf.clone();
}
/**
* Combines a relative date string and a time string in this object's
@ -362,6 +374,20 @@ public final class RelativeDateTimeFormatter {
new Object[]{timeString, relativeDateString}, new StringBuffer(), null).toString();
}
/**
* Returns a copy of the NumberFormat this object is using.
*
* @draft ICU 53
* @provisional
*/
public NumberFormat getNumberFormat() {
// This class is thread-safe, yet numberFormat is not. To ensure thread-safety of this
// class we must guarantee that only one thread at a time uses our numberFormat.
synchronized (numberFormat) {
return (NumberFormat) numberFormat.clone();
}
}
private static void addQualitativeUnit(
EnumMap<AbsoluteUnit, EnumMap<Direction, String>> qualitativeUnits,
AbsoluteUnit unit,

View File

@ -215,18 +215,22 @@ public class RelativeDateTimeFormatterTest extends TestFmwk {
}
}
public void TestSetNumberFormat() {
public void TestCustomNumberFormat() {
ULocale loc = new ULocale("en_US");
NumberFormat nf = NumberFormat.getInstance(loc);
nf.setMinimumFractionDigits(1);
nf.setMaximumFractionDigits(1);
RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(loc);
fmt.setNumberFormat(nf);
RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(loc, nf);
// Change nf after the fact to prove that we made a defensive copy
nf.setMinimumFractionDigits(3);
nf.setMaximumFractionDigits(3);
// Change getNumberFormat to prove we made defensive copy going out.
fmt.getNumberFormat().setMinimumFractionDigits(5);
assertEquals(
"TestCustomNumberformat", 1, fmt.getNumberFormat().getMinimumFractionDigits());
Object[][] data = {
{0.0, Direction.NEXT, RelativeUnit.SECONDS, "in 0.0 seconds"},
{0.5, Direction.NEXT, RelativeUnit.SECONDS, "in 0.5 seconds"},