Get time zone names from CLDR.
Since the intent appears to have been "use the zone's local names if they're in the same country, and use exemplar locations otherwise", this patch gets the localized CLDR time zone name or the localized CLDR exemplar location as appropriate. Bug: 8145760 Bug: 10179879 Change-Id: Ib3968a493de9f0d3040f3afa6ca07d9f44566a32
This commit is contained in:
@@ -34,19 +34,25 @@ import android.widget.SimpleAdapter;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import libcore.icu.ICU;
|
||||
import libcore.icu.TimeZoneNames;
|
||||
|
||||
/**
|
||||
* The class displaying a list of time zones that match a filter string
|
||||
* such as "Africa", "Europe", etc. Choosing an item from the list will set
|
||||
* the time zone. Pressing Back without choosing from the list will not
|
||||
* the time zone. Pressing Back without choosing from the list will not
|
||||
* result in a change in the time zone setting.
|
||||
*/
|
||||
public class ZonePicker extends ListFragment {
|
||||
@@ -98,7 +104,8 @@ public class ZonePicker extends ListFragment {
|
||||
|
||||
final String sortKey = (sortedByName ? KEY_DISPLAYNAME : KEY_OFFSET);
|
||||
final MyComparator comparator = new MyComparator(sortKey);
|
||||
final List<HashMap<String, Object>> sortedList = getZones(context);
|
||||
ZoneGetter zoneGetter = new ZoneGetter();
|
||||
final List<HashMap<String, Object>> sortedList = zoneGetter.getZones(context);
|
||||
Collections.sort(sortedList, comparator);
|
||||
final SimpleAdapter adapter = new SimpleAdapter(context,
|
||||
sortedList,
|
||||
@@ -144,8 +151,8 @@ public class ZonePicker extends ListFragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanseState) {
|
||||
super.onActivityCreated(savedInstanseState);
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
final Activity activity = getActivity();
|
||||
mTimezoneSortedAdapter = constructTimezoneAdapter(activity, false);
|
||||
@@ -217,73 +224,76 @@ public class ZonePicker extends ListFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<HashMap<String, Object>> getZones(Context context) {
|
||||
final List<HashMap<String, Object>> myData = new ArrayList<HashMap<String, Object>>();
|
||||
final long date = Calendar.getInstance().getTimeInMillis();
|
||||
try {
|
||||
XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones);
|
||||
while (xrp.next() != XmlResourceParser.START_TAG)
|
||||
continue;
|
||||
xrp.next();
|
||||
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
|
||||
while (xrp.getEventType() != XmlResourceParser.START_TAG) {
|
||||
if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
|
||||
return myData;
|
||||
static class ZoneGetter {
|
||||
private final List<HashMap<String, Object>> mZones =
|
||||
new ArrayList<HashMap<String, Object>>();
|
||||
private final HashSet<String> mLocalZones = new HashSet<String>();
|
||||
private final Date mNow = Calendar.getInstance().getTime();
|
||||
private final SimpleDateFormat mGmtFormatter = new SimpleDateFormat("ZZZZ");
|
||||
private final SimpleDateFormat mZoneNameFormatter = new SimpleDateFormat("zzzz");
|
||||
|
||||
private List<HashMap<String, Object>> getZones(Context context) {
|
||||
for (String olsonId : TimeZoneNames.forLocale(Locale.getDefault())) {
|
||||
mLocalZones.add(olsonId);
|
||||
}
|
||||
try {
|
||||
XmlResourceParser xrp = context.getResources().getXml(R.xml.timezones);
|
||||
while (xrp.next() != XmlResourceParser.START_TAG) {
|
||||
continue;
|
||||
}
|
||||
xrp.next();
|
||||
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
|
||||
while (xrp.getEventType() != XmlResourceParser.START_TAG) {
|
||||
if (xrp.getEventType() == XmlResourceParser.END_DOCUMENT) {
|
||||
return mZones;
|
||||
}
|
||||
xrp.next();
|
||||
}
|
||||
if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
|
||||
String olsonId = xrp.getAttributeValue(0);
|
||||
addTimeZone(olsonId);
|
||||
}
|
||||
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
|
||||
xrp.next();
|
||||
}
|
||||
xrp.next();
|
||||
}
|
||||
if (xrp.getName().equals(XMLTAG_TIMEZONE)) {
|
||||
String id = xrp.getAttributeValue(0);
|
||||
String displayName = xrp.nextText();
|
||||
addItem(myData, id, displayName, date);
|
||||
}
|
||||
while (xrp.getEventType() != XmlResourceParser.END_TAG) {
|
||||
xrp.next();
|
||||
}
|
||||
xrp.next();
|
||||
xrp.close();
|
||||
} catch (XmlPullParserException xppe) {
|
||||
Log.e(TAG, "Ill-formatted timezones.xml file");
|
||||
} catch (java.io.IOException ioe) {
|
||||
Log.e(TAG, "Unable to read timezones.xml file");
|
||||
}
|
||||
xrp.close();
|
||||
} catch (XmlPullParserException xppe) {
|
||||
Log.e(TAG, "Ill-formatted timezones.xml file");
|
||||
} catch (java.io.IOException ioe) {
|
||||
Log.e(TAG, "Unable to read timezones.xml file");
|
||||
return mZones;
|
||||
}
|
||||
|
||||
return myData;
|
||||
}
|
||||
private void addTimeZone(String olsonId) {
|
||||
// We always need the "GMT-07:00" string.
|
||||
final TimeZone tz = TimeZone.getTimeZone(olsonId);
|
||||
mGmtFormatter.setTimeZone(tz);
|
||||
|
||||
private static void addItem(
|
||||
List<HashMap<String, Object>> myData, String id, String displayName, long date) {
|
||||
final HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
map.put(KEY_ID, id);
|
||||
map.put(KEY_DISPLAYNAME, displayName);
|
||||
final TimeZone tz = TimeZone.getTimeZone(id);
|
||||
final int offset = tz.getOffset(date);
|
||||
final int p = Math.abs(offset);
|
||||
final StringBuilder name = new StringBuilder();
|
||||
name.append("GMT");
|
||||
// For the display name, we treat time zones within the country differently
|
||||
// from other countries' time zones. So in en_US you'd get "Pacific Daylight Time"
|
||||
// but in de_DE you'd get "Los Angeles" for the same time zone.
|
||||
String displayName;
|
||||
if (mLocalZones.contains(olsonId)) {
|
||||
// Within a country, we just use the local name for the time zone.
|
||||
mZoneNameFormatter.setTimeZone(tz);
|
||||
displayName = mZoneNameFormatter.format(mNow);
|
||||
} else {
|
||||
// For other countries' time zones, we use the exemplar location.
|
||||
final String localeName = Locale.getDefault().toString();
|
||||
displayName = TimeZoneNames.getExemplarLocation(localeName, olsonId);
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
name.append('-');
|
||||
} else {
|
||||
name.append('+');
|
||||
final HashMap<String, Object> map = new HashMap<String, Object>();
|
||||
map.put(KEY_ID, olsonId);
|
||||
map.put(KEY_DISPLAYNAME, displayName);
|
||||
map.put(KEY_GMT, mGmtFormatter.format(mNow));
|
||||
map.put(KEY_OFFSET, tz.getOffset(mNow.getTime()));
|
||||
|
||||
mZones.add(map);
|
||||
}
|
||||
|
||||
name.append(p / (HOURS_1));
|
||||
name.append(':');
|
||||
|
||||
int min = p / 60000;
|
||||
min %= 60;
|
||||
|
||||
if (min < 10) {
|
||||
name.append('0');
|
||||
}
|
||||
name.append(min);
|
||||
|
||||
map.put(KEY_GMT, name.toString());
|
||||
map.put(KEY_OFFSET, offset);
|
||||
|
||||
myData.add(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,7 +342,7 @@ public class ZonePicker extends ListFragment {
|
||||
}
|
||||
|
||||
private boolean isComparable(Object value) {
|
||||
return (value != null) && (value instanceof Comparable);
|
||||
return (value != null) && (value instanceof Comparable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user