Merge "Capitalize TZ display name strings"
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.settingslib.datetime;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.icu.text.TimeZoneFormat;
|
||||
@@ -35,6 +36,7 @@ import androidx.core.text.TextDirectionHeuristicsCompat;
|
||||
import com.android.i18n.timezone.CountryTimeZones;
|
||||
import com.android.i18n.timezone.CountryTimeZones.TimeZoneMapping;
|
||||
import com.android.i18n.timezone.TimeZoneFinder;
|
||||
import com.android.internal.app.LocaleHelper;
|
||||
import com.android.settingslib.R;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
@@ -99,7 +101,8 @@ public class ZoneGetter {
|
||||
TimeZoneFormat tzFormatter = TimeZoneFormat.getInstance(locale);
|
||||
CharSequence gmtText = getGmtOffsetText(tzFormatter, locale, tz, now);
|
||||
TimeZoneNames timeZoneNames = TimeZoneNames.getInstance(locale);
|
||||
String zoneNameString = getZoneLongName(timeZoneNames, tz, now);
|
||||
String zoneNameString = capitalizeForStandaloneDisplay(
|
||||
locale, getZoneLongName(locale, timeZoneNames, tz, now));
|
||||
if (zoneNameString == null) {
|
||||
return gmtText;
|
||||
}
|
||||
@@ -108,6 +111,24 @@ public class ZoneGetter {
|
||||
return TextUtils.concat(gmtText, " ", zoneNameString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Capitalizes {@code toCapitalize} for standalone display, i.e. in lists. This is intended for
|
||||
* use with "display name" strings from sources like ICU/CLDR which typically capitalize strings
|
||||
* for the inclusion in the middle of sentences. Some locales (such as Polish) do not capitalize
|
||||
* terms like "Coordinated Universal Time" as in English but do capitalize the first letter for
|
||||
* standalone locations like lists, and so must be explicitly capitalized.
|
||||
*
|
||||
* @return the capitalized string, or {@code null} if the argument is null
|
||||
*/
|
||||
@Nullable
|
||||
public static String capitalizeForStandaloneDisplay(
|
||||
Locale locale, @Nullable String toCapitalize) {
|
||||
if (TextUtils.isEmpty(toCapitalize)) {
|
||||
return toCapitalize;
|
||||
}
|
||||
return LocaleHelper.toSentenceCase(toCapitalize, locale);
|
||||
}
|
||||
|
||||
public static List<Map<String, Object>> getZonesList(Context context) {
|
||||
final Locale locale = context.getResources().getConfiguration().locale;
|
||||
final Date now = new Date();
|
||||
@@ -116,7 +137,7 @@ public class ZoneGetter {
|
||||
|
||||
// Work out whether the display names we would show by default would be ambiguous.
|
||||
final boolean useExemplarLocationForLocalNames =
|
||||
shouldUseExemplarLocationForLocalNames(data, timeZoneNames);
|
||||
shouldUseExemplarLocationForLocalNames(locale, data, timeZoneNames);
|
||||
|
||||
// Generate the list of zone entries to return.
|
||||
List<Map<String, Object>> zones = new ArrayList<Map<String, Object>>();
|
||||
@@ -124,7 +145,7 @@ public class ZoneGetter {
|
||||
TimeZone tz = data.timeZones[i];
|
||||
CharSequence gmtOffsetText = data.gmtOffsetTexts[i];
|
||||
|
||||
CharSequence displayName = getTimeZoneDisplayName(data, timeZoneNames,
|
||||
CharSequence displayName = getTimeZoneDisplayName(locale, data, timeZoneNames,
|
||||
useExemplarLocationForLocalNames, tz, data.olsonIdsToDisplay[i]);
|
||||
if (TextUtils.isEmpty(displayName)) {
|
||||
displayName = gmtOffsetText;
|
||||
@@ -181,15 +202,15 @@ public class ZoneGetter {
|
||||
return olsonIds;
|
||||
}
|
||||
|
||||
private static boolean shouldUseExemplarLocationForLocalNames(ZoneGetterData data,
|
||||
TimeZoneNames timeZoneNames) {
|
||||
private static boolean shouldUseExemplarLocationForLocalNames(Locale locale,
|
||||
ZoneGetterData data, TimeZoneNames timeZoneNames) {
|
||||
final Set<CharSequence> localZoneNames = new HashSet<>();
|
||||
final Date now = new Date();
|
||||
for (int i = 0; i < data.zoneCount; i++) {
|
||||
final String olsonId = data.olsonIdsToDisplay[i];
|
||||
if (data.localZoneIds.contains(olsonId)) {
|
||||
final TimeZone tz = data.timeZones[i];
|
||||
CharSequence displayName = getZoneLongName(timeZoneNames, tz, now);
|
||||
CharSequence displayName = getZoneLongName(locale, timeZoneNames, tz, now);
|
||||
if (displayName == null) {
|
||||
displayName = data.gmtOffsetTexts[i];
|
||||
}
|
||||
@@ -203,7 +224,7 @@ public class ZoneGetter {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static CharSequence getTimeZoneDisplayName(ZoneGetterData data,
|
||||
private static CharSequence getTimeZoneDisplayName(Locale locale, ZoneGetterData data,
|
||||
TimeZoneNames timeZoneNames, boolean useExemplarLocationForLocalNames, TimeZone tz,
|
||||
String olsonId) {
|
||||
final Date now = new Date();
|
||||
@@ -212,7 +233,7 @@ public class ZoneGetter {
|
||||
String displayName;
|
||||
|
||||
if (preferLongName) {
|
||||
displayName = getZoneLongName(timeZoneNames, tz, now);
|
||||
displayName = getZoneLongName(locale, timeZoneNames, tz, now);
|
||||
} else {
|
||||
// Canonicalize the zone ID for ICU. It will only return valid strings for zone IDs
|
||||
// that match ICUs zone IDs (which are similar but not guaranteed the same as those
|
||||
@@ -223,10 +244,11 @@ public class ZoneGetter {
|
||||
if (canonicalZoneId == null) {
|
||||
canonicalZoneId = tz.getID();
|
||||
}
|
||||
displayName = timeZoneNames.getExemplarLocationName(canonicalZoneId);
|
||||
displayName = capitalizeForStandaloneDisplay(
|
||||
locale, timeZoneNames.getExemplarLocationName(canonicalZoneId));
|
||||
if (displayName == null || displayName.isEmpty()) {
|
||||
// getZoneExemplarLocation can return null. Fall back to the long name.
|
||||
displayName = getZoneLongName(timeZoneNames, tz, now);
|
||||
displayName = getZoneLongName(locale, timeZoneNames, tz, now);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,11 +259,13 @@ public class ZoneGetter {
|
||||
* Returns the long name for the timezone for the given locale at the time specified.
|
||||
* Can return {@code null}.
|
||||
*/
|
||||
private static String getZoneLongName(TimeZoneNames names, TimeZone tz, Date now) {
|
||||
private static String getZoneLongName(
|
||||
Locale locale, TimeZoneNames names, TimeZone tz, Date now) {
|
||||
final TimeZoneNames.NameType nameType =
|
||||
tz.inDaylightTime(now) ? TimeZoneNames.NameType.LONG_DAYLIGHT
|
||||
: TimeZoneNames.NameType.LONG_STANDARD;
|
||||
return names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime());
|
||||
return capitalizeForStandaloneDisplay(locale,
|
||||
names.getDisplayName(getCanonicalZoneId(tz), nameType, now.getTime()));
|
||||
}
|
||||
|
||||
private static String getCanonicalZoneId(TimeZone timeZone) {
|
||||
|
||||
Reference in New Issue
Block a user