]> granicus.if.org Git - icu/commitdiff
ICU-10017 Add test for formatPeriod for numeric style and for TimePeriods with just...
authorTravis Keep <keep94@gmail.com>
Thu, 28 Mar 2013 22:25:47 +0000 (22:25 +0000)
committerTravis Keep <keep94@gmail.com>
Thu, 28 Mar 2013 22:25:47 +0000 (22:25 +0000)
X-SVN-Rev: 33475

icu4j/main/classes/core/src/com/ibm/icu/text/TimeUnitFormat.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/TimeUnitTest.java

index d6a4170ba12e3f030561089336074ca05b7a0599..6b7def0664627eb99008b347e96efaf29b014e01 100644 (file)
@@ -100,12 +100,15 @@ public class TimeUnitFormat extends MeasureFormat {
     private transient Map<TimeUnit, Map<String, Object[]>> timeUnitToCountToPatterns;
     private transient PluralRules pluralRules;
     private transient ListFormatter listFormatter;
+    private transient MessageFormat hourMinute;
+    private transient MessageFormat minuteSecond;
+    private transient MessageFormat hourMinuteSecond;
     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;
+    private boolean isNumericStyle;
 
     /**
      * Create empty format using full name style, for example, "hours". 
@@ -148,7 +151,7 @@ public class TimeUnitFormat extends MeasureFormat {
     public TimeUnitFormat(ULocale locale, int style) {
         if (style == NUMERIC) {
             style = ABBREVIATED_NAME;
-            numeric = true;
+            isNumericStyle = true;
         }
         if (style < FULL_NAME || style >= TOTAL_STYLES) {
             throw new IllegalArgumentException("style should be either FULL_NAME or ABBREVIATED_NAME style");
@@ -258,6 +261,12 @@ public class TimeUnitFormat extends MeasureFormat {
         if (!isReady) {
             setup();
         }
+        if (isNumericStyle) {
+            String result = formatPeriodAsNumeric(timePeriod);
+            if (result != null) {
+                return result;
+            }
+        }
         String[] items = new String[timePeriod.size()];
         int idx = 0;
         for (TimeUnitAmount amount : timePeriod) {
@@ -370,6 +379,10 @@ public class TimeUnitFormat extends MeasureFormat {
         }
         pluralRules = PluralRules.forLocale(locale);
         listFormatter = ListFormatter.getInstance(locale);
+        DateTimePatternGenerator df = DateTimePatternGenerator.getInstance(locale);
+        hourMinute = getPattern(df, "hm", locale, "{0}", "{1,number,00.###}", null);
+        minuteSecond = getPattern(df, "ms", locale, null, "{1}", "{2,number,00.###}");
+        hourMinuteSecond = getPattern(df, "hms", locale, "{0}", "{1,number,00}", "{2,number,00.###}");
         timeUnitToCountToPatterns = new HashMap<TimeUnit, Map<String, Object[]>>();
 
         Set<String> pluralKeywords = pluralRules.getKeywords();
@@ -377,7 +390,64 @@ public class TimeUnitFormat extends MeasureFormat {
         setup("unitsShort", timeUnitToCountToPatterns, ABBREVIATED_NAME, pluralKeywords);
         isReady = true;
     }
-
+    
+    private MessageFormat getPattern(DateTimePatternGenerator dtpg, String skeleton, ULocale locale, 
+            String h, String m, String s) {
+        String pat = dtpg.getBestPattern(skeleton);
+        StringBuilder buffer = new StringBuilder();
+        for (Object item : new DateTimePatternGenerator.FormatParser().set(pat).getItems()) {
+            if (item instanceof DateTimePatternGenerator.VariableField) {
+                DateTimePatternGenerator.VariableField fld = (DateTimePatternGenerator.VariableField)item;
+                switch (fld.getType()) {
+                case DateTimePatternGenerator.HOUR: buffer.append(h); break;
+                case DateTimePatternGenerator.MINUTE: buffer.append(m); break;
+                case DateTimePatternGenerator.SECOND: buffer.append(s); break;
+                }
+            } else {
+                buffer.append(item);
+            }
+        }
+        return new MessageFormat(buffer.toString(), locale);
+    }
+    
+    private String formatPeriodAsNumeric(TimePeriod timePeriod) {
+        TimeUnit biggestUnit = null, smallestUnit = null;
+        for (TimeUnitAmount tua : timePeriod) {
+            if (biggestUnit == null) {
+                biggestUnit = tua.getTimeUnit();
+            }
+            smallestUnit = tua.getTimeUnit();
+        }
+        // We have to trim the result of  MessageFormat.format() not sure why.
+        if (biggestUnit == TimeUnit.HOUR && smallestUnit == TimeUnit.SECOND) {
+            return hourMinuteSecond.format(new Object[]{
+                    getZeroedAmount(timePeriod, TimeUnit.HOUR),
+                    getZeroedAmount(timePeriod, TimeUnit.MINUTE),
+                    getZeroedAmount(timePeriod, TimeUnit.SECOND)}).trim();
+            
+        }
+        if (biggestUnit == TimeUnit.MINUTE && smallestUnit == TimeUnit.SECOND) {
+            return minuteSecond.format(new Object[]{
+                    null,
+                    getZeroedAmount(timePeriod, TimeUnit.MINUTE),
+                    getZeroedAmount(timePeriod, TimeUnit.SECOND)}).trim();
+            
+        }
+        if (biggestUnit == TimeUnit.HOUR && smallestUnit == TimeUnit.MINUTE) {
+            return hourMinute.format(new Object[]{
+                    getZeroedAmount(timePeriod, TimeUnit.HOUR),
+                    getZeroedAmount(timePeriod, TimeUnit.MINUTE)}).trim();            
+        }
+        return null;
+    }
+    
+    private Number getZeroedAmount(TimePeriod timePeriod, TimeUnit timeUnit) {
+        TimeUnitAmount tua = timePeriod.getAmount(timeUnit);
+        if (tua == null) {
+            return Double.valueOf(0);
+        }
+        return tua.getNumber();
+    }
 
     private void setup(String resourceKey, Map<TimeUnit, Map<String, Object[]>> timeUnitToCountToPatterns,
                        int style, Set<String> pluralKeywords) {
index 84b63f74aa41948b3134d5cbd933e0e37a535bb7..63bce4530873cada7184b913a33f09852911e621 100644 (file)
@@ -23,7 +23,11 @@ import com.ibm.icu.util.ULocale;
  *
  */
 public class TimeUnitTest extends TestFmwk {
-    
+    private static final TimePeriod _19m = TimePeriod.forAmounts(
+            new TimeUnitAmount(19.0, TimeUnit.MINUTE));
+    private static final TimePeriod _19m_28s = TimePeriod.forAmounts(
+            new TimeUnitAmount(19.0, TimeUnit.MINUTE),
+            new TimeUnitAmount(28.0, TimeUnit.SECOND));
     private static final TimePeriod _1h_23_5s = TimePeriod.forAmounts(
             new TimeUnitAmount(1.0, TimeUnit.HOUR),
             new TimeUnitAmount(23.5, TimeUnit.SECOND));
@@ -31,6 +35,9 @@ public class TimeUnitTest extends TestFmwk {
             new TimeUnitAmount(1.0, TimeUnit.HOUR),
             new TimeUnitAmount(0.0, TimeUnit.MINUTE),
             new TimeUnitAmount(23.0, TimeUnit.SECOND));
+    private static final TimePeriod _5h_17m = TimePeriod.forAmounts(
+            new TimeUnitAmount(5.0, TimeUnit.HOUR),
+            new TimeUnitAmount(17.0, TimeUnit.MINUTE));
     private static final TimePeriod _2y_5M_3w_4d = TimePeriod.forAmounts(
             new TimeUnitAmount(2.0, TimeUnit.YEAR),
             new TimeUnitAmount(5.0, TimeUnit.MONTH),
@@ -342,25 +349,42 @@ public class TimeUnitTest extends TestFmwk {
     
     public void TestFormatPeriodEn() {
         Object[][] fullData = {
+                {_19m, "19 minutes"},
                 {_1h_23_5s, "1 hour and 23.5 seconds"},
                 {_1h_0m_23s, "1 hour, 0 minutes, and 23 seconds"},
                 {_2y_5M_3w_4d, "2 years, 5 months, 3 weeks, and 4 days"}};
+        Object[][] abbrevData = {
+                {_19m, "19 mins"},
+                {_1h_23_5s, "1 hr and 23.5 secs"},
+                {_1h_0m_23s, "1 hr, 0 mins, and 23 secs"},
+                {_2y_5M_3w_4d, "2 yrs, 5 mths, 3 wks, and 4 days"}};
+        Object[][] numericData = {
+                {_19m, "19 mins"},
+                {_1h_23_5s, "1:00:23.5"},
+                {_1h_0m_23s, "1:00:23"},
+                {_5h_17m, "5:17"},
+                {_19m_28s, "19:28"},
+                {_2y_5M_3w_4d, "2 yrs, 5 mths, 3 wks, and 4 days"}};
         TimeUnitFormat tuf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.FULL_NAME);
         verifyFormatPeriod("en FULL", tuf, fullData);
+        tuf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.ABBREVIATED_NAME);
+        verifyFormatPeriod("en ABBREV", tuf, abbrevData);       
+        tuf = new TimeUnitFormat(ULocale.ENGLISH, TimeUnitFormat.NUMERIC);
+        verifyFormatPeriod("en NUMERIC", tuf, numericData);
     }
     
     private void verifyFormatPeriod(String desc, TimeUnitFormat tuf, Object[][] testData) {
+        StringBuilder builder = new StringBuilder();
         boolean failure = false;
         for (Object[] testCase : testData) {
-            try {
-                assertEquals(desc, testCase[1], tuf.formatTimePeriod((TimePeriod) testCase[0]));
-            } catch (RuntimeException e) {
-                logln(e.getMessage());
+            String actual = tuf.formatTimePeriod((TimePeriod) testCase[0]);
+            if (!testCase[1].equals(actual)) {
+                builder.append(String.format("%s: Expected: '%s', got: '%s'\n", desc, testCase[1], actual));
                 failure = true;
             }
         }
         if (failure) {
-            errln("Test failed.");
+            errln(builder.toString());
         }
     }
 }