diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java b/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java index 7dd08b91fc6..6f47fe0a7c1 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/RelativeDateTimeFormatter.java @@ -50,46 +50,46 @@ import com.ibm.icu.util.UResourceBundle; * fmt.format(1, Direction.NEXT, RelativeUnit.DAYS); // "in 1 day" * fmt.format(3, Direction.NEXT, RelativeUnit.DAYS); // "in 3 days" * fmt.format(3.2, Direction.LAST, RelativeUnit.YEARS); // "3.2 years ago" - * + * * fmt.format(Direction.LAST, AbsoluteUnit.SUNDAY); // "last Sunday" * fmt.format(Direction.THIS, AbsoluteUnit.SUNDAY); // "this Sunday" * fmt.format(Direction.NEXT, AbsoluteUnit.SUNDAY); // "next Sunday" * fmt.format(Direction.PLAIN, AbsoluteUnit.SUNDAY); // "Sunday" - * + * * fmt.format(Direction.LAST, AbsoluteUnit.DAY); // "yesterday" * fmt.format(Direction.THIS, AbsoluteUnit.DAY); // "today" * fmt.format(Direction.NEXT, AbsoluteUnit.DAY); // "tomorrow" - * + * * fmt.format(Direction.PLAIN, AbsoluteUnit.NOW); // "now" * * *

* In the future, we may add more forms, such as abbreviated/short forms * (3 secs ago), and relative day periods ("yesterday afternoon"), etc. - * + * * @stable ICU 53 */ public final class RelativeDateTimeFormatter { - + /** * The formatting style * @stable ICU 54 * */ public static enum Style { - + /** * Everything spelled out. * @stable ICU 54 */ LONG, - + /** * Abbreviations used when possible. * @stable ICU 54 */ SHORT, - + /** * Use single letters when possible. * @stable ICU 54 @@ -105,43 +105,43 @@ public final class RelativeDateTimeFormatter { * @stable ICU 53 */ public static enum RelativeUnit { - + /** * Seconds * @stable ICU 53 */ SECONDS, - + /** * Minutes * @stable ICU 53 */ MINUTES, - + /** * Hours * @stable ICU 53 */ HOURS, - + /** * Days * @stable ICU 53 */ DAYS, - + /** * Weeks * @stable ICU 53 */ WEEKS, - + /** * Months * @stable ICU 53 */ MONTHS, - + /** * Years * @stable ICU 53 @@ -156,79 +156,79 @@ public final class RelativeDateTimeFormatter { @Deprecated QUARTERS, } - + /** * Represents an absolute unit. * @stable ICU 53 */ public static enum AbsoluteUnit { - + /** * Sunday * @stable ICU 53 */ SUNDAY, - + /** * Monday * @stable ICU 53 */ MONDAY, - + /** * Tuesday * @stable ICU 53 */ TUESDAY, - + /** * Wednesday * @stable ICU 53 */ WEDNESDAY, - + /** * Thursday * @stable ICU 53 */ THURSDAY, - + /** * Friday * @stable ICU 53 */ FRIDAY, - + /** * Saturday * @stable ICU 53 */ SATURDAY, - + /** * Day * @stable ICU 53 */ DAY, - + /** * Week * @stable ICU 53 */ WEEK, - + /** * Month * @stable ICU 53 */ MONTH, - + /** * Year * @stable ICU 53 */ YEAR, - + /** * Now * @stable ICU 53 @@ -259,7 +259,7 @@ public final class RelativeDateTimeFormatter { /** * Last * @stable ICU 53 - */ + */ LAST, /** @@ -294,107 +294,107 @@ public final class RelativeDateTimeFormatter { * @provisional This API might change or be removed in a future release. */ public static enum RelativeDateTimeUnit { - /** + /** * Specifies that relative unit is year, e.g. "last year", - * "in 5 years". + * "in 5 years". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ YEAR, - /** + /** * Specifies that relative unit is quarter, e.g. "last quarter", - * "in 5 quarters". + * "in 5 quarters". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ QUARTER, - /** + /** * Specifies that relative unit is month, e.g. "last month", - * "in 5 months". + * "in 5 months". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ MONTH, - /** + /** * Specifies that relative unit is week, e.g. "last week", - * "in 5 weeks". + * "in 5 weeks". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ WEEK, - /** + /** * Specifies that relative unit is day, e.g. "yesterday", - * "in 5 days". + * "in 5 days". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ DAY, - /** + /** * Specifies that relative unit is hour, e.g. "1 hour ago", - * "in 5 hours". + * "in 5 hours". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ HOUR, - /** + /** * Specifies that relative unit is minute, e.g. "1 minute ago", - * "in 5 minutes". + * "in 5 minutes". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ MINUTE, - /** + /** * Specifies that relative unit is second, e.g. "1 second ago", - * "in 5 seconds". + * "in 5 seconds". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ SECOND, - /** + /** * Specifies that relative unit is Sunday, e.g. "last Sunday", - * "this Sunday", "next Sunday", "in 5 Sundays". + * "this Sunday", "next Sunday", "in 5 Sundays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ SUNDAY, - /** + /** * Specifies that relative unit is Monday, e.g. "last Monday", - * "this Monday", "next Monday", "in 5 Mondays". + * "this Monday", "next Monday", "in 5 Mondays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ MONDAY, - /** + /** * Specifies that relative unit is Tuesday, e.g. "last Tuesday", - * "this Tuesday", "next Tuesday", "in 5 Tuesdays". + * "this Tuesday", "next Tuesday", "in 5 Tuesdays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ TUESDAY, - /** + /** * Specifies that relative unit is Wednesday, e.g. "last Wednesday", - * "this Wednesday", "next Wednesday", "in 5 Wednesdays". + * "this Wednesday", "next Wednesday", "in 5 Wednesdays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ WEDNESDAY, - /** + /** * Specifies that relative unit is Thursday, e.g. "last Thursday", - * "this Thursday", "next Thursday", "in 5 Thursdays". + * "this Thursday", "next Thursday", "in 5 Thursdays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ THURSDAY, - /** + /** * Specifies that relative unit is Friday, e.g. "last Friday", - * "this Friday", "next Friday", "in 5 Fridays". + * "this Friday", "next Friday", "in 5 Fridays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ FRIDAY, - /** + /** * Specifies that relative unit is Saturday, e.g. "last Saturday", - * "this Saturday", "next Saturday", "in 5 Saturdays". + * "this Saturday", "next Saturday", "in 5 Saturdays". * @draft ICU 57 * @provisional This API might change or be removed in a future release. */ @@ -411,7 +411,7 @@ public final class RelativeDateTimeFormatter { /** * Returns a RelativeDateTimeFormatter for a particular locale. - * + * * @param locale the locale. * @return An instance of RelativeDateTimeFormatter. * @stable ICU 53 @@ -422,7 +422,7 @@ public final class RelativeDateTimeFormatter { /** * Returns a RelativeDateTimeFormatter for a particular {@link java.util.Locale}. - * + * * @param locale the {@link java.util.Locale}. * @return An instance of RelativeDateTimeFormatter. * @stable ICU 54 @@ -434,21 +434,21 @@ public final class RelativeDateTimeFormatter { /** * 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. + * and immutability of this class. * @return An instance of RelativeDateTimeFormatter. * @stable ICU 53 */ public static RelativeDateTimeFormatter getInstance(ULocale locale, NumberFormat nf) { return getInstance(locale, nf, Style.LONG, DisplayContext.CAPITALIZATION_NONE); } - + /** * Returns a RelativeDateTimeFormatter for a particular locale that uses a particular * NumberFormat object, style, and capitalization context - * + * * @param locale the locale * @param nf the number format object. It is defensively copied to ensure thread-safety * and immutability of this class. May be null. @@ -484,10 +484,10 @@ public final class RelativeDateTimeFormatter { /** * Returns a RelativeDateTimeFormatter for a particular {@link java.util.Locale} that uses a * particular NumberFormat object. - * + * * @param locale the {@link java.util.Locale} * @param nf the number format object. It is defensively copied to ensure thread-safety - * and immutability of this class. + * and immutability of this class. * @return An instance of RelativeDateTimeFormatter. * @stable ICU 54 */ @@ -534,7 +534,7 @@ public final class RelativeDateTimeFormatter { * Format a combination of RelativeDateTimeUnit and numeric offset * using a numeric style, e.g. "1 week ago", "in 1 week", * "5 weeks ago", "in 5 weeks". - * + * * @param offset The signed offset for the specified unit. This * will be formatted according to this object's * NumberFormat object. @@ -564,7 +564,7 @@ public final class RelativeDateTimeFormatter { case MINUTE: relunit = RelativeUnit.MINUTES; break; case SECOND: break; // set above default: // SUNDAY..SATURDAY - return ""; + throw new UnsupportedOperationException("formatNumeric does not currently support RelativeUnit.SUNDAY..SATURDAY"); } Direction direction = Direction.NEXT; if (offset < 0) { @@ -574,7 +574,7 @@ public final class RelativeDateTimeFormatter { String result = format(offset, direction, relunit); return (result != null)? result: ""; } - + private int[] styleToDateFormatSymbolsWidth = { DateFormatSymbols.WIDE, DateFormatSymbols.SHORT, DateFormatSymbols.NARROW }; @@ -617,7 +617,7 @@ public final class RelativeDateTimeFormatter { * "next week", "yesterday", "tomorrow". Falls back to numeric * style if no appropriate text term is available for the specified * offset in the object’s locale. - * + * * @param offset The signed offset for the specified field. * @param unit The unit to use when formatting the relative * date, e.g. RelativeDateTimeUnit.WEEK, @@ -634,18 +634,20 @@ public final class RelativeDateTimeFormatter { // new CLDR data is available, update the data storage accordingly, rewrite this // to use it directly, and rewrite the old format method to call this new one; // that is covered by http://bugs.icu-project.org/trac/ticket/12171. - boolean useNumeric = false; + boolean useNumeric = true; Direction direction = Direction.THIS; - int intoffset = (offset < 0)? (int)(offset-0.5) : (int)(offset+0.5); - switch (intoffset) { - case -2: direction = Direction.LAST_2; break; - case -1: direction = Direction.LAST; break; - case 0: break; // direction = Direction.THIS was set above - case 1: direction = Direction.NEXT; break; - case 2: direction = Direction.NEXT_2; break; - default: - useNumeric = true; - break; + if (offset > -2.1 && offset < 2.1) { + // Allow a 1% epsilon, so offsets in -1.01..-0.99 map to LAST + double offsetx100 = offset * 100.0; + int intoffset = (offsetx100 < 0)? (int)(offsetx100-0.5) : (int)(offsetx100+0.5); + switch (intoffset) { + case -200/*-2*/: direction = Direction.LAST_2; useNumeric = false; break; + case -100/*-1*/: direction = Direction.LAST; useNumeric = false; break; + case 0/* 0*/: useNumeric = false; break; // direction = Direction.THIS was set above + case 100/* 1*/: direction = Direction.NEXT; useNumeric = false; break; + case 200/* 2*/: direction = Direction.NEXT_2; useNumeric = false; break; + default: break; + } } AbsoluteUnit absunit = AbsoluteUnit.NOW; switch (unit) { @@ -661,7 +663,6 @@ public final class RelativeDateTimeFormatter { case THURSDAY: absunit = AbsoluteUnit.THURSDAY; break; case FRIDAY: absunit = AbsoluteUnit.FRIDAY; break; case SATURDAY: absunit = AbsoluteUnit.SATURDAY; break; - case MINUTE: case SECOND: if (direction == Direction.THIS) { // absunit = AbsoluteUnit.NOW was set above @@ -751,7 +752,7 @@ public final class RelativeDateTimeFormatter { /** * Return style - * @return The formatting style. + * @return The formatting style. * @stable ICU 54 */ public Style getFormatStyle() { @@ -759,7 +760,7 @@ public final class RelativeDateTimeFormatter { } private String adjustForContext(String originalFormattedString) { - if (breakIterator == null || originalFormattedString.length() == 0 + if (breakIterator == null || originalFormattedString.length() == 0 || !UCharacter.isLowerCase(UCharacter.codePointAt(originalFormattedString, 0))) { return originalFormattedString; } @@ -774,7 +775,7 @@ public final class RelativeDateTimeFormatter { private RelativeDateTimeFormatter( EnumMap>> qualitativeUnitMap, - EnumMap> patternMap, + EnumMap> patternMap, String combinedDateAndTime, PluralRules pluralRules, NumberFormat numberFormat, @@ -1058,7 +1059,7 @@ public final class RelativeDateTimeFormatter { throw new ICUException( "Inconsistent style fallback for style " + sourceStyle + " to " + targetStyle); } - } + } } @Override @@ -1077,7 +1078,7 @@ public final class RelativeDateTimeFormatter { } // Sinks for additional levels under /fields/*/relative/ and /fields/*/relativeTime/ - + // Sets values under relativeTime paths, e.g., "hour/relativeTime/future/one" class RelativeTimeDetailSink extends UResource.TableSink { @Override @@ -1126,7 +1127,7 @@ public final class RelativeDateTimeFormatter { } } RelativeTimeSink relativeTimeSink = new RelativeTimeSink(); - + // Handles "relative" entries, e.g., under "day", "day-short", "fri", "fri-narrow", "fri-short", etc. class RelativeSink extends UResource.TableSink { @Override diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java index 577833ecc97..b5e9c755993 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/RelativeDateTimeFormatterTest.java @@ -21,11 +21,11 @@ import com.ibm.icu.text.RelativeDateTimeFormatter.Style; import com.ibm.icu.util.ULocale; public class RelativeDateTimeFormatterTest extends TestFmwk { - + public static void main(String[] args) throws Exception { new RelativeDateTimeFormatterTest().run(args); } - + public void TestRelativeDateWithQuantity() { Object[][] data = { {0.0, Direction.NEXT, RelativeUnit.SECONDS, "in 0 seconds"}, @@ -56,7 +56,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.5, Direction.NEXT, RelativeUnit.YEARS, "in 0.5 years"}, {1.0, Direction.NEXT, RelativeUnit.YEARS, "in 1 year"}, {2.0, Direction.NEXT, RelativeUnit.YEARS, "in 2 years"}, - + {0.0, Direction.LAST, RelativeUnit.SECONDS, "0 seconds ago"}, {0.5, Direction.LAST, RelativeUnit.SECONDS, "0.5 seconds ago"}, {1.0, Direction.LAST, RelativeUnit.SECONDS, "1 second ago"}, @@ -84,7 +84,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.0, Direction.LAST, RelativeUnit.YEARS, "0 years ago"}, {0.5, Direction.LAST, RelativeUnit.YEARS, "0.5 years ago"}, {1.0, Direction.LAST, RelativeUnit.YEARS, "1 year ago"}, - {2.0, Direction.LAST, RelativeUnit.YEARS, "2 years ago"}, + {2.0, Direction.LAST, RelativeUnit.YEARS, "2 years ago"}, }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(new ULocale("en_US")); for (Object[] row : data) { @@ -93,12 +93,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity", row[3], actual); } } - + public void TestRelativeDateWithQuantityCaps() { Object[][] data = { {0.0, Direction.NEXT, RelativeUnit.SECONDS, "In 0 seconds"}, {0.5, Direction.NEXT, RelativeUnit.SECONDS, "In 0.5 seconds"}, - + {1.0, Direction.NEXT, RelativeUnit.SECONDS, "In 1 second"}, {2.0, Direction.NEXT, RelativeUnit.SECONDS, "In 2 seconds"}, {0.0, Direction.NEXT, RelativeUnit.MINUTES, "In 0 minutes"}, @@ -125,7 +125,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.5, Direction.NEXT, RelativeUnit.YEARS, "In 0.5 years"}, {1.0, Direction.NEXT, RelativeUnit.YEARS, "In 1 year"}, {2.0, Direction.NEXT, RelativeUnit.YEARS, "In 2 years"}, - + {0.0, Direction.LAST, RelativeUnit.SECONDS, "0 seconds ago"}, {0.5, Direction.LAST, RelativeUnit.SECONDS, "0.5 seconds ago"}, {1.0, Direction.LAST, RelativeUnit.SECONDS, "1 second ago"}, @@ -153,8 +153,8 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.0, Direction.LAST, RelativeUnit.YEARS, "0 years ago"}, {0.5, Direction.LAST, RelativeUnit.YEARS, "0.5 years ago"}, {1.0, Direction.LAST, RelativeUnit.YEARS, "1 year ago"}, - {2.0, Direction.LAST, RelativeUnit.YEARS, "2 years ago"}, - + {2.0, Direction.LAST, RelativeUnit.YEARS, "2 years ago"}, + }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("en_US"), @@ -167,12 +167,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity", row[3], actual); } } - + public void TestRelativeDateWithQuantityShort() { Object[][] data = { {0.0, Direction.NEXT, RelativeUnit.SECONDS, "in 0 sec."}, {0.5, Direction.NEXT, RelativeUnit.SECONDS, "in 0.5 sec."}, - + {1.0, Direction.NEXT, RelativeUnit.SECONDS, "in 1 sec."}, {2.0, Direction.NEXT, RelativeUnit.SECONDS, "in 2 sec."}, {0.0, Direction.NEXT, RelativeUnit.MINUTES, "in 0 min."}, @@ -199,7 +199,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.5, Direction.NEXT, RelativeUnit.YEARS, "in 0.5 yr."}, {1.0, Direction.NEXT, RelativeUnit.YEARS, "in 1 yr."}, {2.0, Direction.NEXT, RelativeUnit.YEARS, "in 2 yr."}, - + {0.0, Direction.LAST, RelativeUnit.SECONDS, "0 sec. ago"}, {0.5, Direction.LAST, RelativeUnit.SECONDS, "0.5 sec. ago"}, {1.0, Direction.LAST, RelativeUnit.SECONDS, "1 sec. ago"}, @@ -227,8 +227,8 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.0, Direction.LAST, RelativeUnit.YEARS, "0 yr. ago"}, {0.5, Direction.LAST, RelativeUnit.YEARS, "0.5 yr. ago"}, {1.0, Direction.LAST, RelativeUnit.YEARS, "1 yr. ago"}, - {2.0, Direction.LAST, RelativeUnit.YEARS, "2 yr. ago"}, - + {2.0, Direction.LAST, RelativeUnit.YEARS, "2 yr. ago"}, + }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("en_US"), @@ -241,12 +241,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity", row[3], actual); } } - + public void TestRelativeDateWithQuantityNarrow() { Object[][] data = { {0.0, Direction.NEXT, RelativeUnit.SECONDS, "in 0 sec."}, {0.5, Direction.NEXT, RelativeUnit.SECONDS, "in 0.5 sec."}, - + {1.0, Direction.NEXT, RelativeUnit.SECONDS, "in 1 sec."}, {2.0, Direction.NEXT, RelativeUnit.SECONDS, "in 2 sec."}, {0.0, Direction.NEXT, RelativeUnit.MINUTES, "in 0 min."}, @@ -273,7 +273,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.5, Direction.NEXT, RelativeUnit.YEARS, "in 0.5 yr."}, {1.0, Direction.NEXT, RelativeUnit.YEARS, "in 1 yr."}, {2.0, Direction.NEXT, RelativeUnit.YEARS, "in 2 yr."}, - + {0.0, Direction.LAST, RelativeUnit.SECONDS, "0 sec. ago"}, {0.5, Direction.LAST, RelativeUnit.SECONDS, "0.5 sec. ago"}, {1.0, Direction.LAST, RelativeUnit.SECONDS, "1 sec. ago"}, @@ -301,8 +301,8 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {0.0, Direction.LAST, RelativeUnit.YEARS, "0 yr. ago"}, {0.5, Direction.LAST, RelativeUnit.YEARS, "0.5 yr. ago"}, {1.0, Direction.LAST, RelativeUnit.YEARS, "1 yr. ago"}, - {2.0, Direction.LAST, RelativeUnit.YEARS, "2 yr. ago"}, - + {2.0, Direction.LAST, RelativeUnit.YEARS, "2 yr. ago"}, + }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("en_US"), @@ -315,14 +315,14 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity", row[3], actual); } } - - - + + + public void TestRelativeDateWithQuantitySr() { Object[][] data = { {0.0, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 0 \u043C\u0435\u0441\u0435\u0446\u0438"}, {1.2, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 1,2 \u043C\u0435\u0441\u0435\u0446\u0430"}, - {21.0, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 21 \u043C\u0435\u0441\u0435\u0446"}, + {21.0, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 21 \u043C\u0435\u0441\u0435\u0446"}, }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(new ULocale("sr")); for (Object[] row : data) { @@ -331,12 +331,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity", row[3], actual); } } - + public void TestRelativeDateWithQuantitySrFallback() { Object[][] data = { {0.0, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 0 \u043C."}, {1.2, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 1,2 \u043C."}, - {21.0, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 21 \u043C."}, + {21.0, Direction.NEXT, RelativeUnit.MONTHS, "\u0437\u0430 21 \u043C."}, }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("sr"), @@ -349,11 +349,11 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity fallback", row[3], actual); } } - + public void TestRelativeDateWithoutQuantity() { Object[][] data = { {Direction.NEXT_2, AbsoluteUnit.DAY, null}, - + {Direction.NEXT, AbsoluteUnit.DAY, "tomorrow"}, {Direction.NEXT, AbsoluteUnit.WEEK, "next week"}, {Direction.NEXT, AbsoluteUnit.MONTH, "next month"}, @@ -365,9 +365,9 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.NEXT, AbsoluteUnit.FRIDAY, "next Friday"}, {Direction.NEXT, AbsoluteUnit.SATURDAY, "next Saturday"}, {Direction.NEXT, AbsoluteUnit.SUNDAY, "next Sunday"}, - + {Direction.LAST_2, AbsoluteUnit.DAY, null}, - + {Direction.LAST, AbsoluteUnit.DAY, "yesterday"}, {Direction.LAST, AbsoluteUnit.WEEK, "last week"}, {Direction.LAST, AbsoluteUnit.MONTH, "last month"}, @@ -379,7 +379,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.LAST, AbsoluteUnit.FRIDAY, "last Friday"}, {Direction.LAST, AbsoluteUnit.SATURDAY, "last Saturday"}, {Direction.LAST, AbsoluteUnit.SUNDAY, "last Sunday"}, - + {Direction.THIS, AbsoluteUnit.DAY, "today"}, {Direction.THIS, AbsoluteUnit.WEEK, "this week"}, {Direction.THIS, AbsoluteUnit.MONTH, "this month"}, @@ -391,7 +391,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.THIS, AbsoluteUnit.FRIDAY, "this Friday"}, {Direction.THIS, AbsoluteUnit.SATURDAY, "this Saturday"}, {Direction.THIS, AbsoluteUnit.SUNDAY, "this Sunday"}, - + {Direction.PLAIN, AbsoluteUnit.DAY, "day"}, {Direction.PLAIN, AbsoluteUnit.WEEK, "week"}, {Direction.PLAIN, AbsoluteUnit.MONTH, "month"}, @@ -403,7 +403,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.PLAIN, AbsoluteUnit.FRIDAY, "Friday"}, {Direction.PLAIN, AbsoluteUnit.SATURDAY, "Saturday"}, {Direction.PLAIN, AbsoluteUnit.SUNDAY, "Sunday"}, - + {Direction.PLAIN, AbsoluteUnit.NOW, "now"}, }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(new ULocale("en_US")); @@ -412,16 +412,16 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date without quantity", row[2], actual); } } - + public void TestRelativeDateWithoutQuantityCaps() { Object[][] data = { {Direction.NEXT_2, AbsoluteUnit.DAY, null}, - + {Direction.NEXT, AbsoluteUnit.DAY, "Tomorrow"}, - {Direction.NEXT, AbsoluteUnit.WEEK, "Next week"}, + {Direction.NEXT, AbsoluteUnit.WEEK, "Next week"}, {Direction.NEXT, AbsoluteUnit.MONTH, "Next month"}, {Direction.NEXT, AbsoluteUnit.YEAR, "Next year"}, - + {Direction.NEXT, AbsoluteUnit.MONDAY, "Next Monday"}, {Direction.NEXT, AbsoluteUnit.TUESDAY, "Next Tuesday"}, {Direction.NEXT, AbsoluteUnit.WEDNESDAY, "Next Wednesday"}, @@ -429,9 +429,9 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.NEXT, AbsoluteUnit.FRIDAY, "Next Friday"}, {Direction.NEXT, AbsoluteUnit.SATURDAY, "Next Saturday"}, {Direction.NEXT, AbsoluteUnit.SUNDAY, "Next Sunday"}, - + {Direction.LAST_2, AbsoluteUnit.DAY, null}, - + {Direction.LAST, AbsoluteUnit.DAY, "Yesterday"}, {Direction.LAST, AbsoluteUnit.WEEK, "Last week"}, {Direction.LAST, AbsoluteUnit.MONTH, "Last month"}, @@ -443,7 +443,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.LAST, AbsoluteUnit.FRIDAY, "Last Friday"}, {Direction.LAST, AbsoluteUnit.SATURDAY, "Last Saturday"}, {Direction.LAST, AbsoluteUnit.SUNDAY, "Last Sunday"}, - + {Direction.THIS, AbsoluteUnit.DAY, "Today"}, {Direction.THIS, AbsoluteUnit.WEEK, "This week"}, {Direction.THIS, AbsoluteUnit.MONTH, "This month"}, @@ -455,7 +455,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.THIS, AbsoluteUnit.FRIDAY, "This Friday"}, {Direction.THIS, AbsoluteUnit.SATURDAY, "This Saturday"}, {Direction.THIS, AbsoluteUnit.SUNDAY, "This Sunday"}, - + {Direction.PLAIN, AbsoluteUnit.DAY, "Day"}, {Direction.PLAIN, AbsoluteUnit.WEEK, "Week"}, {Direction.PLAIN, AbsoluteUnit.MONTH, "Month"}, @@ -467,9 +467,9 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.PLAIN, AbsoluteUnit.FRIDAY, "Friday"}, {Direction.PLAIN, AbsoluteUnit.SATURDAY, "Saturday"}, {Direction.PLAIN, AbsoluteUnit.SUNDAY, "Sunday"}, - + {Direction.PLAIN, AbsoluteUnit.NOW, "Now"}, - + }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("en_US"), @@ -481,28 +481,28 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date without quantity caps", row[2], actual); } } - + public void TestRelativeDateWithoutQuantityShort() { Object[][] data = { {Direction.NEXT_2, AbsoluteUnit.DAY, null}, - + {Direction.NEXT, AbsoluteUnit.DAY, "tomorrow"}, {Direction.NEXT, AbsoluteUnit.WEEK, "next wk."}, - + {Direction.NEXT, AbsoluteUnit.MONTH, "next mo."}, {Direction.NEXT, AbsoluteUnit.YEAR, "next yr."}, - + {Direction.NEXT, AbsoluteUnit.MONDAY, "next Mon."}, - + {Direction.NEXT, AbsoluteUnit.TUESDAY, "next Tue."}, {Direction.NEXT, AbsoluteUnit.WEDNESDAY, "next Wed."}, {Direction.NEXT, AbsoluteUnit.THURSDAY, "next Thu."}, {Direction.NEXT, AbsoluteUnit.FRIDAY, "next Fri."}, {Direction.NEXT, AbsoluteUnit.SATURDAY, "next Sat."}, {Direction.NEXT, AbsoluteUnit.SUNDAY, "next Sun."}, - + {Direction.LAST_2, AbsoluteUnit.DAY, null}, - + {Direction.LAST, AbsoluteUnit.DAY, "yesterday"}, {Direction.LAST, AbsoluteUnit.WEEK, "last wk."}, {Direction.LAST, AbsoluteUnit.MONTH, "last mo."}, @@ -511,12 +511,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.LAST, AbsoluteUnit.TUESDAY, "last Tue."}, {Direction.LAST, AbsoluteUnit.WEDNESDAY, "last Wed."}, {Direction.LAST, AbsoluteUnit.THURSDAY, "last Thu."}, - + {Direction.LAST, AbsoluteUnit.FRIDAY, "last Fri."}, - + {Direction.LAST, AbsoluteUnit.SATURDAY, "last Sat."}, {Direction.LAST, AbsoluteUnit.SUNDAY, "last Sun."}, - + {Direction.THIS, AbsoluteUnit.DAY, "today"}, {Direction.THIS, AbsoluteUnit.WEEK, "this wk."}, {Direction.THIS, AbsoluteUnit.MONTH, "this mo."}, @@ -528,7 +528,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.THIS, AbsoluteUnit.FRIDAY, "this Fri."}, {Direction.THIS, AbsoluteUnit.SATURDAY, "this Sat."}, {Direction.THIS, AbsoluteUnit.SUNDAY, "this Sun."}, - + {Direction.PLAIN, AbsoluteUnit.DAY, "day"}, {Direction.PLAIN, AbsoluteUnit.WEEK, "wk."}, {Direction.PLAIN, AbsoluteUnit.MONTH, "mo."}, @@ -540,9 +540,9 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.PLAIN, AbsoluteUnit.FRIDAY, "Fr"}, {Direction.PLAIN, AbsoluteUnit.SATURDAY, "Sa"}, {Direction.PLAIN, AbsoluteUnit.SUNDAY, "Su"}, - + {Direction.PLAIN, AbsoluteUnit.NOW, "now"}, - + }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("en_US"), @@ -554,28 +554,28 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date without quantity short", row[2], actual); } } - + public void TestRelativeDateWithoutQuantityNarrow() { Object[][] data = { {Direction.NEXT_2, AbsoluteUnit.DAY, null}, - + {Direction.NEXT, AbsoluteUnit.DAY, "tomorrow"}, {Direction.NEXT, AbsoluteUnit.WEEK, "next wk."}, - + {Direction.NEXT, AbsoluteUnit.MONTH, "next mo."}, {Direction.NEXT, AbsoluteUnit.YEAR, "next yr."}, - + {Direction.NEXT, AbsoluteUnit.MONDAY, "next M"}, - + {Direction.NEXT, AbsoluteUnit.TUESDAY, "next Tu"}, {Direction.NEXT, AbsoluteUnit.WEDNESDAY, "next W"}, {Direction.NEXT, AbsoluteUnit.THURSDAY, "next Th"}, {Direction.NEXT, AbsoluteUnit.FRIDAY, "next F"}, {Direction.NEXT, AbsoluteUnit.SATURDAY, "next Sa"}, {Direction.NEXT, AbsoluteUnit.SUNDAY, "next Su"}, - + {Direction.LAST_2, AbsoluteUnit.DAY, null}, - + {Direction.LAST, AbsoluteUnit.DAY, "yesterday"}, {Direction.LAST, AbsoluteUnit.WEEK, "last wk."}, {Direction.LAST, AbsoluteUnit.MONTH, "last mo."}, @@ -587,7 +587,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.LAST, AbsoluteUnit.FRIDAY, "last F"}, {Direction.LAST, AbsoluteUnit.SATURDAY, "last Sa"}, {Direction.LAST, AbsoluteUnit.SUNDAY, "last Su"}, - + {Direction.THIS, AbsoluteUnit.DAY, "today"}, {Direction.THIS, AbsoluteUnit.WEEK, "this wk."}, {Direction.THIS, AbsoluteUnit.MONTH, "this mo."}, @@ -596,12 +596,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.THIS, AbsoluteUnit.TUESDAY, "this Tu"}, {Direction.THIS, AbsoluteUnit.WEDNESDAY, "this W"}, {Direction.THIS, AbsoluteUnit.THURSDAY, "this Th"}, - + {Direction.THIS, AbsoluteUnit.FRIDAY, "this F"}, - + {Direction.THIS, AbsoluteUnit.SATURDAY, "this Sa"}, {Direction.THIS, AbsoluteUnit.SUNDAY, "this Su"}, - + {Direction.PLAIN, AbsoluteUnit.DAY, "day"}, {Direction.PLAIN, AbsoluteUnit.WEEK, "wk."}, {Direction.PLAIN, AbsoluteUnit.MONTH, "mo."}, @@ -613,9 +613,9 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { {Direction.PLAIN, AbsoluteUnit.FRIDAY, "F"}, {Direction.PLAIN, AbsoluteUnit.SATURDAY, "S"}, {Direction.PLAIN, AbsoluteUnit.SUNDAY, "S"}, - + {Direction.PLAIN, AbsoluteUnit.NOW, "now"}, - + }; RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance( new ULocale("en_US"), @@ -629,18 +629,19 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { } public void TestRelativeDateTimeUnitFormatters() { - double[] offsets = { -5.0, -2.2, -1.0, -0.7, 0.0, 0.7, 1.0, 2.2, 5.0 }; + double[] offsets = { -5.0, -2.2, -2.0, -1.0, -0.7, 0.0, 0.7, 1.0, 2.0, 5.0 }; String[] en_decDef_long_midSent_week = { /* text numeric */ "5 weeks ago", "5 weeks ago", /* -5 */ "2.2 weeks ago", "2.2 weeks ago", /* -2.2 */ + "2 weeks ago", "2 weeks ago", /* -2 */ "last week", "1 week ago", /* -1 */ - "last week", "0.7 weeks ago", /* -0.7 */ + "0.7 weeks ago", "0.7 weeks ago", /* -0.7 */ "this week", "in 0 weeks", /* 0 */ - "next week", "in 0.7 weeks", /* 0.7 */ + "in 0.7 weeks", "in 0.7 weeks", /* 0.7 */ "next week", "in 1 week", /* 1 */ - "in 2.2 weeks", "in 2.2 weeks", /* 2.2 */ + "in 2 weeks", "in 2 weeks", /* 2 */ "in 5 weeks", "in 5 weeks" /* 5 */ }; @@ -648,12 +649,13 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { /* text numeric */ "5 weeks ago", "5 weeks ago", /* -5 */ "2 weeks ago", "2 weeks ago", /* -2.2 */ + "2 weeks ago", "2 weeks ago", /* -2 */ "last week", "1 week ago", /* -1 */ - "last week", "0 weeks ago", /* -0.7 */ + "0 weeks ago", "0 weeks ago", /* -0.7 */ "this week", "in 0 weeks", /* 0 */ - "next week", "in 0 weeks", /* 0.7 */ + "in 0 weeks", "in 0 weeks", /* 0.7 */ "next week", "in 1 week", /* 1 */ - "in 2 weeks", "in 2 weeks", /* 2.2 */ + "in 2 weeks", "in 2 weeks", /* 2 */ "in 5 weeks", "in 5 weeks" /* 5 */ }; @@ -661,12 +663,13 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { /* text numeric */ "5 wk. ago", "5 wk. ago", /* -5 */ "2.2 wk. ago", "2.2 wk. ago", /* -2.2 */ + "2 wk. ago", "2 wk. ago", /* -2 */ "last wk.", "1 wk. ago", /* -1 */ - "last wk.", "0.7 wk. ago", /* -0.7 */ + "0.7 wk. ago", "0.7 wk. ago", /* -0.7 */ "this wk.", "in 0 wk.", /* 0 */ - "next wk.", "in 0.7 wk.", /* 0.7 */ + "in 0.7 wk.", "in 0.7 wk.", /* 0.7 */ "next wk.", "in 1 wk.", /* 1 */ - "in 2.2 wk.", "in 2.2 wk.", /* 2.2 */ + "in 2 wk.", "in 2 wk.", /* 2 */ "in 5 wk.", "in 5 wk." /* 5 */ }; @@ -674,12 +677,13 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { /* text numeric */ "5 minutes ago", "5 minutes ago", /* -5 */ "2.2 minutes ago", "2.2 minutes ago", /* -2.2 */ + "2 minutes ago", "2 minutes ago", /* -2 */ "1 minute ago", "1 minute ago", /* -1 */ "0.7 minutes ago", "0.7 minutes ago", /* -0.7 */ - "now", "in 0 minutes", /* 0 */ + "in 0 minutes", "in 0 minutes", /* 0 */ "in 0.7 minutes", "in 0.7 minutes", /* 0.7 */ "in 1 minute", "in 1 minute", /* 1 */ - "in 2.2 minutes", "in 2.2 minutes", /* 2.2 */ + "in 2 minutes", "in 2 minutes", /* 2 */ "in 5 minutes", "in 5 minutes" /* 5 */ }; @@ -687,25 +691,27 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { /* text numeric */ ""/*no data */, ""/*no data */, /* -5 */ ""/*no data */, ""/*no data */, /* -2.2 */ + ""/*no data */, ""/*no data */, /* -2 */ "last Tuesday", ""/*no data */, /* -1 */ - "last Tuesday", ""/*no data */, /* -0.7 */ + ""/*no data */, ""/*no data */, /* -0.7 */ "this Tuesday", ""/*no data */, /* 0 */ - "next Tuesday", ""/*no data */, /* 0.7 */ + ""/*no data */, ""/*no data */, /* 0.7 */ "next Tuesday", ""/*no data */, /* 1 */ - ""/*no data */, ""/*no data */, /* 2.2 */ + ""/*no data */, ""/*no data */, /* 2 */ ""/*no data */, ""/*no data */, /* 5 */ }; String[] fr_decDef_long_midSent_day = { /* text numeric */ "il y a 5 jours", "il y a 5 jours", /* -5 */ - "avant-hier", "il y a 2,2 jours", /* -2.2 */ + "il y a 2,2 jours", "il y a 2,2 jours", /* -2.2 */ + "avant-hier", "il y a 2 jours", /* -2 */ "hier", "il y a 1 jour", /* -1 */ - "hier", "il y a 0,7 jour", /* -0.7 */ - "aujourd\u2019hui", "dans 0 jour", /* 0 */ - "demain", "dans 0,7 jour", /* 0.7 */ + "il y a 0,7 jour", "il y a 0,7 jour", /* -0.7 */ + "aujourd’hui", "dans 0 jour", /* 0 */ + "dans 0,7 jour", "dans 0,7 jour", /* 0.7 */ "demain", "dans 1 jour", /* 1 */ - "apr\u00E8s-demain", "dans 2,2 jours", /* 2.2 */ + "après-demain", "dans 2 jours", /* 2 */ "dans 5 jours", "dans 5 jours" /* 5 */ }; @@ -752,7 +758,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { RelativeDateTimeFormatter reldatefmt = RelativeDateTimeFormatter.getInstance(uloc, nf, item.width, item.capContext); for (int iOffset = 0; iOffset < offsets.length; iOffset++) { double offset = offsets[iOffset]; - if (item.unit == RelativeDateTimeUnit.TUESDAY && (offset < -1.0 || offset > 1.0)) { + if (item.unit == RelativeDateTimeUnit.TUESDAY && offset != -1.0 && offset != 0.0 && offset != 1.0) { continue; /* we do not currently have data for this */ } String result = reldatefmt.format(offset, item.unit); @@ -768,7 +774,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { } } } - + public void TestTwoBeforeTwoAfter() { Object[][] data = { {Direction.NEXT_2, AbsoluteUnit.DAY, "pasado ma\u00F1ana"}, @@ -780,7 +786,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Two before two after", row[2], actual); } } - + public void TestFormatWithQuantityIllegalArgument() { RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(new ULocale("en_US")); try { @@ -791,12 +797,12 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { } try { fmt.format(1.0, Direction.THIS, RelativeUnit.DAYS); - fail("Expected IllegalArgumentException."); + fail("Expected IllegalArgumentException."); } catch (IllegalArgumentException e) { // Expected } } - + public void TestFormatWithoutQuantityIllegalArgument() { RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(new ULocale("en_US")); try { @@ -818,23 +824,23 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { // Expected } } - + 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, 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"}, @@ -847,7 +853,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { assertEquals("Relative date with quantity special NumberFormat", row[3], actual); } } - + public void TestCombineDateAndTime() { RelativeDateTimeFormatter fmt = RelativeDateTimeFormatter.getInstance(new ULocale("en_US")); assertEquals("TestcombineDateAndTime", "yesterday, 3:50", fmt.combineDateAndTime("yesterday", "3:50")); @@ -881,7 +887,7 @@ public class RelativeDateTimeFormatterTest extends TestFmwk { DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, fmt.getCapitalizationContext()); } - + public void TestBadDisplayContext() { try { RelativeDateTimeFormatter.getInstance(