/*
*******************************************************************************
- * Copyright (C) 2007-2013, International Business Machines Corporation and *
+ * Copyright (C) 2007-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
import java.util.Set;
import java.util.TreeSet;
+import com.ibm.icu.lang.UCharacter;
+import com.ibm.icu.lang.UProperty;
import com.ibm.icu.text.DateFormat;
+import com.ibm.icu.text.DisplayContext;
import com.ibm.icu.text.MessageFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
FieldPosition fieldPosition) {
String relativeDayString = null;
+ DisplayContext capitalizationContext = getContext(DisplayContext.Type.CAPITALIZATION);
+
if (fDateStyle != DateFormat.NONE) {
// calculate the difference, in days, between 'cal' and now.
int dayDiff = dayDifference(cal);
relativeDayString = getStringForDay(dayDiff);
}
+ if ( relativeDayString != null && fDatePattern != null &&
+ (fTimePattern == null || fCombinedFormat == null || combinedFormatHasDateAtStart) ) {
+ // capitalize relativeDayString according to context for tense, set formatter no context
+ if ( capitalizationContext == DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
+ (capitalizationContext == DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU && capitalizationForRelativeUnitsListOrMenu) ||
+ (capitalizationContext == DisplayContext.CAPITALIZATION_FOR_STANDALONE && capitalizationForRelativeUnitsStandAlone) ) {
+ // titlecase first word of relativeDayString, do like LocaleDisplayNamesImpl.adjustForUsageAndContext
+ // Note that for languages that *have* case, using the word break properties here works reasonably
+ // well (CLDR word break tailoring is for non-casing languages, and the POSIX locale).
+ int stopPos, stopPosLimit = 8, len = relativeDayString.length();
+ if ( stopPosLimit > len ) {
+ stopPosLimit = len;
+ }
+ for ( stopPos = 0; stopPos < stopPosLimit; stopPos++ ) {
+ int ch = relativeDayString.codePointAt(stopPos);
+ int wb = UCharacter.getIntPropertyValue(ch, UProperty.WORD_BREAK);
+ if ( !(UCharacter.isLowerCase(ch) || wb==UCharacter.WordBreak.EXTEND || wb==UCharacter.WordBreak.SINGLE_QUOTE ||
+ wb==UCharacter.WordBreak.MIDNUMLET || wb==UCharacter.WordBreak.MIDLETTER) ) {
+ break;
+ }
+ if (ch >= 0x10000) {
+ stopPos++;
+ }
+ }
+ if ( stopPos > 0 && stopPos < len ) {
+ String firstWord = relativeDayString.substring(0, stopPos);
+ firstWord = UCharacter.toTitleCase(fLocale, firstWord, null,
+ UCharacter.TITLECASE_NO_LOWERCASE | UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT);
+ relativeDayString = firstWord.concat(relativeDayString.substring(stopPos));
+ } else {
+ // no stopPos, titlecase the whole text
+ relativeDayString = UCharacter.toTitleCase(fLocale, relativeDayString, null,
+ UCharacter.TITLECASE_NO_LOWERCASE | UCharacter.TITLECASE_NO_BREAK_ADJUSTMENT);
+ }
+ }
+ fDateTimeFormat.setContext(DisplayContext.CAPITALIZATION_NONE);
+ } else {
+ // set our context for the formatter
+ fDateTimeFormat.setContext(capitalizationContext);
+ }
+
if (fDateTimeFormat != null && (fDatePattern != null || fTimePattern != null)) {
// The new way
if (fDatePattern == null) {
private transient URelativeString fDates[] = null; // array of strings
+ private transient boolean capitalizationForRelativeUnitsListOrMenu = false;
+ private transient boolean capitalizationForRelativeUnitsStandAlone = false;
+ private transient boolean combinedFormatHasDateAtStart = false;
+
/**
* Get the string at a specific offset.
datesSet.add(rs);
}
fDates = datesSet.toArray(new URelativeString[0]);
+
+ try {
+ rdb = rb.getWithFallback("contextTransforms/tense");
+ int[] intVector = rdb.getIntVector();
+ if (intVector.length >= 2) {
+ capitalizationForRelativeUnitsListOrMenu = (intVector[0] != 0);
+ capitalizationForRelativeUnitsStandAlone = (intVector[1] != 0);
+ }
+ } catch (MissingResourceException e) {
+ // use default
+ }
}
/**
} catch (MissingResourceException e) {
// use default
}
+ combinedFormatHasDateAtStart = pattern.startsWith("{1}");
fCombinedFormat = new MessageFormat(pattern, locale);
return fCombinedFormat;
}
/*
*******************************************************************************
- * Copyright (C) 2001-2013, International Business Machines Corporation and *
+ * Copyright (C) 2001-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
new TestContextItem( "cs", "LLLL y", DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU, "\u010Cervenec 2008" ),
new TestContextItem( "cs", "LLLL y", DisplayContext.CAPITALIZATION_FOR_STANDALONE, "\u010Dervenec 2008" ),
};
+ class TestRelativeContextItem {
+ public String locale;
+ public DisplayContext capitalizationContext;
+ public String expectedFormatToday;
+ public String expectedFormatYesterday;
+ // Simple constructor
+ public TestRelativeContextItem(String loc, DisplayContext capCtxt, String expFmtToday, String expFmtYesterday) {
+ locale = loc;
+ capitalizationContext = capCtxt;
+ expectedFormatToday = expFmtToday;
+ expectedFormatYesterday = expFmtYesterday;
+ }
+ };
+ final TestRelativeContextItem[] relItems = {
+ new TestRelativeContextItem( "en", DisplayContext.CAPITALIZATION_NONE, "today", "yesterday" ),
+ new TestRelativeContextItem( "en", DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, "today", "yesterday" ),
+ new TestRelativeContextItem( "en", DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, "Today", "Yesterday" ),
+ new TestRelativeContextItem( "en", DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU, "Today", "Yesterday" ),
+ new TestRelativeContextItem( "en", DisplayContext.CAPITALIZATION_FOR_STANDALONE, "Today", "Yesterday" ),
+ new TestRelativeContextItem( "nb", DisplayContext.CAPITALIZATION_NONE, "i dag", "i g\u00E5r" ),
+ new TestRelativeContextItem( "nb", DisplayContext.CAPITALIZATION_FOR_MIDDLE_OF_SENTENCE, "i dag", "i g\u00E5r" ),
+ new TestRelativeContextItem( "nb", DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE, "I dag", "I g\u00E5r" ),
+ new TestRelativeContextItem( "nb", DisplayContext.CAPITALIZATION_FOR_UI_LIST_OR_MENU, "i dag", "i g\u00E5r" ),
+ new TestRelativeContextItem( "nb", DisplayContext.CAPITALIZATION_FOR_STANDALONE, "I dag", "I g\u00E5r" ),
+ };
+
Calendar cal = new GregorianCalendar(2008, Calendar.JULY, 2);
for (TestContextItem item: items) {
ULocale locale = new ULocale(item.locale);
FieldPosition fpos2 = new FieldPosition(0);
sdfmt.format(cal, result2, fpos2);
if (result2.toString().compareTo(item.expectedFormat) != 0) {
- errln("FAIL: format (default context) for locale " + item.locale + ", capitalizationContext " + item.capitalizationContext +
+ errln("FAIL: format for locale " + item.locale + ", capitalizationContext " + item.capitalizationContext +
", expected \"" + item.expectedFormat + "\", got \"" + result2 + "\"");
}
- // now read back context, make sure it is what we set
+ // now read back context, make sure it is what we set (testing with DateFormat subclass)
DisplayContext capitalizationContext = sdfmt.getContext(DisplayContext.Type.CAPITALIZATION);
if (capitalizationContext != item.capitalizationContext) {
- errln("FAIL: getDefaultContext for locale " + item.locale + ", capitalizationContext " + item.capitalizationContext +
+ errln("FAIL: getContext for locale " + item.locale + ", capitalizationContext " + item.capitalizationContext +
+ ", but got context " + capitalizationContext);
+ }
+ }
+ for (TestRelativeContextItem relItem: relItems) {
+ ULocale locale = new ULocale(relItem.locale);
+ DateFormat dfmt = DateFormat.getDateInstance(DateFormat.RELATIVE_LONG, locale);
+ Date today = new Date();
+
+ // now try context & standard format call
+ dfmt.setContext(relItem.capitalizationContext);
+ cal.setTime(today);
+ StringBuffer result2 = new StringBuffer();
+ FieldPosition fpos2 = new FieldPosition(0);
+ dfmt.format(cal, result2, fpos2);
+ if (result2.toString().compareTo(relItem.expectedFormatToday) != 0) {
+ errln("FAIL: format today for locale " + relItem.locale + ", capitalizationContext " + relItem.capitalizationContext +
+ ", expected \"" + relItem.expectedFormatToday + "\", got \"" + result2 + "\"");
+ }
+ cal.add(Calendar.DATE, -1);
+ result2.setLength(0);
+ dfmt.format(cal, result2, fpos2);
+ if (result2.toString().compareTo(relItem.expectedFormatYesterday) != 0) {
+ errln("FAIL: format yesterday for locale " + relItem.locale + ", capitalizationContext " + relItem.capitalizationContext +
+ ", expected \"" + relItem.expectedFormatYesterday + "\", got \"" + result2 + "\"");
+ }
+
+ // now read back context, make sure it is what we set (testing with DateFormat itself)
+ DisplayContext capitalizationContext = dfmt.getContext(DisplayContext.Type.CAPITALIZATION);
+ if (capitalizationContext != relItem.capitalizationContext) {
+ errln("FAIL: getContext for locale " + relItem.locale + ", capitalizationContext " + relItem.capitalizationContext +
", but got context " + capitalizationContext);
}
}