From b35aa4dcf7c1f5685eb2d0ae050ac01eec20af75 Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Thu, 28 Mar 2013 17:38:18 +0000 Subject: [PATCH] ICU-10017 Add API specification for composition of time periods for ICU4J into code. X-SVN-Rev: 33471 --- .gitattributes | 1 + .../src/com/ibm/icu/text/TimeUnitFormat.java | 31 +++++- .../core/src/com/ibm/icu/util/TimePeriod.java | 94 +++++++++++++++++++ .../ibm/icu/dev/test/format/TimeUnitTest.java | 28 +++--- 4 files changed, 138 insertions(+), 16 deletions(-) create mode 100644 icu4j/main/classes/core/src/com/ibm/icu/util/TimePeriod.java diff --git a/.gitattributes b/.gitattributes index c4968b1dee3..2d1fffcd852 100644 --- a/.gitattributes +++ b/.gitattributes @@ -248,6 +248,7 @@ icu4j/main/classes/core/.project -text icu4j/main/classes/core/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/core/.settings/org.eclipse.jdt.core.prefs -text icu4j/main/classes/core/manifest.stub -text +icu4j/main/classes/core/src/com/ibm/icu/util/TimePeriod.java -text icu4j/main/classes/currdata/.externalToolBuilders/copy-data-currdata.launch -text icu4j/main/classes/currdata/.settings/org.eclipse.core.resources.prefs -text icu4j/main/classes/currdata/.settings/org.eclipse.jdt.core.prefs -text diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/TimeUnitFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/TimeUnitFormat.java index 44193975b8e..ad068557d12 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/TimeUnitFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/TimeUnitFormat.java @@ -1,6 +1,6 @@ /* ************************************************************************** - * Copyright (C) 2008-2012, Google, International Business Machines + * Copyright (C) 2008-2013, Google, International Business Machines * Corporation and others. All Rights Reserved. ************************************************************************** */ @@ -17,6 +17,7 @@ import java.util.Set; import java.util.TreeMap; import com.ibm.icu.impl.ICUResourceBundle; +import com.ibm.icu.util.TimePeriod; import com.ibm.icu.util.TimeUnit; import com.ibm.icu.util.TimeUnitAmount; import com.ibm.icu.util.ULocale; @@ -70,7 +71,16 @@ public class TimeUnitFormat extends MeasureFormat { * @stable ICU 4.2 */ public static final int ABBREVIATED_NAME = 1; + + /** + * Constant for numeric style format. + * NUMERIC strives to be as brief as possible. For example: 3:05:47. + * @draft ICU 52 + */ + public static final int NUMERIC = 2; + // For now we don't consider NUMERIC a full-fledged style. NUMERIC is + // congruent to ABBREVIATED_NAME unless formatPeriod() is being called. private static final int TOTAL_STYLES = 2; private static final long serialVersionUID = -3707773153184971529L; @@ -89,6 +99,10 @@ public class TimeUnitFormat extends MeasureFormat { private transient PluralRules pluralRules; private transient boolean isReady; private int style; + + // When style is set to NUMERIC, this field is set to true and the style + // field becomes ABBREVIATED_NAME. + private boolean numeric; /** * Create empty format using full name style, for example, "hours". @@ -129,6 +143,10 @@ public class TimeUnitFormat extends MeasureFormat { * @stable ICU 4.2 */ public TimeUnitFormat(ULocale locale, int style) { + if (style == NUMERIC) { + style = ABBREVIATED_NAME; + numeric = true; + } if (style < FULL_NAME || style >= TOTAL_STYLES) { throw new IllegalArgumentException("style should be either FULL_NAME or ABBREVIATED_NAME style"); } @@ -226,7 +244,16 @@ public class TimeUnitFormat extends MeasureFormat { MessageFormat pattern = (MessageFormat)(countToPattern.get(count))[style]; return pattern.format(new Object[]{amount.getNumber()}, toAppendTo, pos); } - + + /** + * Formats a TimePeriod. Currently there is no way to parse a formatted TimePeriod. + * @param timePeriod the TimePeriod to format. + * @return the formatted string. + * @draft ICU 52 + */ + public String formatTimePeriod(TimePeriod timePeriod) { + return null; + } /** * Parse a TimeUnitAmount. diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/TimePeriod.java b/icu4j/main/classes/core/src/com/ibm/icu/util/TimePeriod.java new file mode 100644 index 00000000000..a761d58b975 --- /dev/null +++ b/icu4j/main/classes/core/src/com/ibm/icu/util/TimePeriod.java @@ -0,0 +1,94 @@ +/* + ******************************************************************************* + * Copyright (C) 2013, International Business Machines Corporation and * + * others. All Rights Reserved. * + ******************************************************************************* + */ +package com.ibm.icu.util; + +import java.util.Iterator; + +/** + * TimePeriod represents a time period. TimePeriod objects are immutable. + *

Example usage: + *

+ *   Period p = Period.forAmounts(
+ *       new TimeUnitAmount (TimeUnit.WEEK, 5),
+ *       new TimeUnitAmount (TimeUnit.DAY, 40),
+ *       new TimeUnitAmount (TimeUnit.HOUR, 2),
+ *       new TimeUnitAmount (TimeUnit.SECOND, 8));
+ * 
+ * @draft ICU 52 + */ +public final class TimePeriod implements Iterable { + + /** + * Returns a new TimePeriod that matches the given time unit amounts. + * @param amounts the TimeUnitAmounts. Must be non-empty. Normalization of the + * amounts and inclusion/exclusion of 0 amounts is up to caller. + * @return the new TimePeriod object + * @throws IllegalArgumentException if multiple TimeUnitAmount objects match + * the same time unit or if any but the smallest TimeUnit has a fractional value + * Or if amounts is empty. + * @draft ICU 52 + */ + public static TimePeriod forAmounts(TimeUnitAmount ...amounts) { + return null; + } + + /** + * Returns a new TimePeriod that matches the given time unit amounts. + * @param amounts the TimeUnitAmounts. Must be non-empty. Normalization of the + * amounts and inclusion/exclusion of 0 amounts is up to caller. + * @return the new TimePeriod object + * @throws IllegalArgumentException if multiple TimeUnitAmount objects match + * the same time unit or if any but the smallest TimeUnit has a fractional value + * Or if amounts is empty. + * @draft ICU 52 + */ + public static TimePeriod forAmounts(Iterable amounts) { + return null; + } + + /** + * Gets the value for a specific time unit. + * @param timeUnit the time unit. + * @return the TimeUnitAmount or null if no value is present for given TimeUnit. + * A non-existing value and a zero value are two different things. + * @draft ICU 52 + */ + public TimeUnitAmount getAmount(TimeUnit timeUnit) { + return null; + } + + /** + * Returned iterator iterates over all TimeUnitAmount objects in this object. + * Iterated TimeUnitAmount objects are ordered from largest TimeUnit to + * smallest TimeUnit. + * @draft ICU 52 + */ + public Iterator iterator() { + return null; + } + + /** + * Returns the number of TimeUnitAmount objects in this object. + */ + public int size() { + return 0; + } + + /** + * Two TimePeriod objects are equal if they contain equal TimeUnitAmount objects. + */ + @Override + public boolean equals(Object rhs) { + return true; + } + + @Override + public int hashCode() { + return 0; + } +} + diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TimeUnitTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TimeUnitTest.java index 61201767101..f3fb789fb4f 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TimeUnitTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TimeUnitTest.java @@ -1,6 +1,6 @@ /* ******************************************************************************* - * Copyright (C) 2008-2012, International Business Machines Corporation and * + * Copyright (C) 2008-2013, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ @@ -30,12 +30,14 @@ public class TimeUnitTest extends TestFmwk { String[] locales = {"en", "sl", "fr", "zh", "ar", "ru", "zh_Hant"}; for ( int locIndex = 0; locIndex < locales.length; ++locIndex ) { //System.out.println("locale: " + locales[locIndex]); - Object[] formats = new Object[] { + TimeUnitFormat[] formats = new TimeUnitFormat[] { new TimeUnitFormat(new ULocale(locales[locIndex]), TimeUnitFormat.FULL_NAME), - new TimeUnitFormat(new ULocale(locales[locIndex]), TimeUnitFormat.ABBREVIATED_NAME) + new TimeUnitFormat(new ULocale(locales[locIndex]), TimeUnitFormat.ABBREVIATED_NAME), + new TimeUnitFormat(new ULocale(locales[locIndex]), TimeUnitFormat.NUMERIC) + }; for (int style = TimeUnitFormat.FULL_NAME; - style <= TimeUnitFormat.ABBREVIATED_NAME; + style <= TimeUnitFormat.NUMERIC; ++style) { final TimeUnit[] values = TimeUnit.values(); for (int j = 0; j < values.length; ++j) { @@ -43,18 +45,16 @@ public class TimeUnitTest extends TestFmwk { double[] tests = {0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 5, 10, 100, 101.35}; for (int i = 0; i < tests.length; ++i) { TimeUnitAmount source = new TimeUnitAmount(tests[i], timeUnit); - String formatted = ((TimeUnitFormat)formats[style]).format(source); + String formatted = formats[style].format(source); //System.out.println(formatted); logln(tests[i] + " => " + formatted); try { - TimeUnitAmount result = (TimeUnitAmount) ((TimeUnitFormat)formats[style]).parseObject(formatted); - if (result == null || !source.equals(result)) { - errln("No round trip: " + source + " => " + formatted + " => " + result); - } - // mix style parsing - result = (TimeUnitAmount) ((TimeUnitFormat)formats[1 - style]).parseObject(formatted); - if (result == null || !source.equals(result)) { - errln("No round trip: " + source + " => " + formatted + " => " + result); + // Style should not matter when parsing. + for (int parseStyle = TimeUnitFormat.FULL_NAME; parseStyle <= TimeUnitFormat.NUMERIC; parseStyle++) { + TimeUnitAmount result = (TimeUnitAmount) formats[parseStyle].parseObject(formatted); + if (result == null || !source.equals(result)) { + errln("No round trip: " + source + " => " + formatted + " => " + result); + } } } catch (ParseException e) { errln(e.getMessage()); @@ -230,7 +230,7 @@ public class TimeUnitTest extends TestFmwk { public void TestTimeUnitFormat() { // Tests when "if (style < FULL_NAME || style >= TOTAL_STYLES)" is true // TOTAL_STYLES is 2 - int[] cases = { TimeUnitFormat.FULL_NAME - 1, TimeUnitFormat.FULL_NAME - 2, 2, 3 }; + int[] cases = { TimeUnitFormat.FULL_NAME - 1, TimeUnitFormat.FULL_NAME - 2, 3 }; for (int i = 0; i < cases.length; i++) { try { TimeUnitFormat tuf = new TimeUnitFormat(new ULocale("en_US"), cases[i]);