Sort timezones in timezone picker

Bug: 7596888
Change-Id: Ia122cf85c36f402008b5cbf6249481cb9605126b
diff --git a/src/com/android/deskclock/SettingsActivity.java b/src/com/android/deskclock/SettingsActivity.java
index ffdf1af..ef2243f 100644
--- a/src/com/android/deskclock/SettingsActivity.java
+++ b/src/com/android/deskclock/SettingsActivity.java
@@ -33,6 +33,9 @@
 
 import com.android.deskclock.worldclock.Cities;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.TimeZone;
 
 /**
@@ -64,7 +67,6 @@
     private static CharSequence[][] mTimezones;
     private long mTime;
 
-    private static final boolean SHOW_DAYLIGHT_SAVINGS_INDICATOR = false;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -214,6 +216,52 @@
         SnoozeLengthDialog snoozePref = (SnoozeLengthDialog) findPreference(KEY_ALARM_SNOOZE);
         snoozePref.setSummary();
     }
+
+    private class TimeZoneRow implements Comparable<TimeZoneRow> {
+        private static final boolean SHOW_DAYLIGHT_SAVINGS_INDICATOR = false;
+
+        public final String mId;
+        public final String mDisplayName;
+        public final int mOffset;
+
+        public TimeZoneRow(String id, String name) {
+            mId = id;
+            TimeZone tz = TimeZone.getTimeZone(id);
+            boolean useDaylightTime = tz.useDaylightTime();
+            mOffset = tz.getOffset(mTime);
+            mDisplayName = buildGmtDisplayName(id, name, useDaylightTime);
+        }
+
+        @Override
+        public int compareTo(TimeZoneRow another) {
+            return mOffset - another.mOffset;
+        }
+
+        public String buildGmtDisplayName(String id, String displayName, boolean useDaylightTime) {
+            int p = Math.abs(mOffset);
+            StringBuilder name = new StringBuilder("(GMT");
+            name.append(mOffset < 0 ? '-' : '+');
+
+            name.append(p / DateUtils.HOUR_IN_MILLIS);
+            name.append(':');
+
+            int min = p / 60000;
+            min %= 60;
+
+            if (min < 10) {
+                name.append('0');
+            }
+            name.append(min);
+            name.append(") ");
+            name.append(displayName);
+            if (useDaylightTime && SHOW_DAYLIGHT_SAVINGS_INDICATOR) {
+                name.append(" \u2600"); // Sun symbol
+            }
+            return name.toString();
+        }
+    }
+
+
     /**
      * Returns an array of ids/time zones. This returns a double indexed array
      * of ids and time zones for Calendar. It is an inefficient method and
@@ -229,44 +277,19 @@
         if (ids.length != labels.length) {
             Log.wtf("Timezone ids and labels have different length!");
         }
-        CharSequence[][] timeZones = new CharSequence[2][ids.length];
+        List<TimeZoneRow> timezones = new ArrayList<TimeZoneRow>();
         for (int i = 0; i < ids.length; i++) {
-            timeZones[0][i] = ids[i];
-            timeZones[1][i] = buildGmtDisplayName(ids[i], labels[i]);
+            timezones.add(new TimeZoneRow(ids[i], labels[i]));
+        }
+        Collections.sort(timezones);
+
+        CharSequence[][] timeZones = new CharSequence[2][timezones.size()];
+        int i = 0;
+        for (TimeZoneRow row : timezones) {
+            timeZones[0][i] = row.mId;
+            timeZones[1][i++] = row.mDisplayName;
         }
         return timeZones;
     }
 
-    public String buildGmtDisplayName(String id, String displayName) {
-        TimeZone tz = TimeZone.getTimeZone(id);
-        boolean mUseDaylightTime = tz.useDaylightTime();
-        int mOffset = tz.getOffset(mTime);
-        int p = Math.abs(mOffset);
-        StringBuilder name = new StringBuilder();
-        name.append("GMT");
-
-        if (mOffset < 0) {
-            name.append('-');
-        } else {
-            name.append('+');
-        }
-
-        name.append(p / (DateUtils.HOUR_IN_MILLIS));
-        name.append(':');
-
-        int min = p / 60000;
-        min %= 60;
-
-        if (min < 10) {
-            name.append('0');
-        }
-        name.append(min);
-        name.insert(0, "(");
-        name.append(") ");
-        name.append(displayName);
-        if (mUseDaylightTime && SHOW_DAYLIGHT_SAVINGS_INDICATOR) {
-            name.append(" \u2600"); // Sun symbol
-        }
-        return name.toString();
-    }
 }