diff --git a/tests/uitests/src/com/android/settings/ui/ZonePickerSettingsTest.java b/tests/uitests/src/com/android/settings/ui/ZonePickerSettingsTest.java
new file mode 100644
index 0000000..109c3bc
--- /dev/null
+++ b/tests/uitests/src/com/android/settings/ui/ZonePickerSettingsTest.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.ui;
+
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+import android.support.test.uiautomator.UiScrollable;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.Until;
+import android.system.helpers.SettingsHelper;
+import android.system.helpers.SettingsHelper.SettingsType;
+import android.widget.ListView;
+import android.widget.Spinner;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.TimeZone;
+
+import static com.android.settings.ui.testutils.SettingsTestUtils.SETTINGS_PACKAGE;
+import static com.android.settings.ui.testutils.SettingsTestUtils.TIMEOUT;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class ZonePickerSettingsTest {
+
+    private static final BySelector SELECTOR_SELECT_TIME_ZONE =
+            By.hasChild(By.text("Select time zone"));
+
+    private UiDevice mDevice;
+    private SettingsHelper mHelper;
+    private String mIsV2EnabledByDefault;
+    private int mIsAutoZoneEnabled;
+
+    @Before
+    public void setUp() throws Exception {
+        mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+        mHelper = SettingsHelper.getInstance();
+        try {
+            mDevice.setOrientationNatural();
+        } catch (RemoteException e) {
+            throw new RuntimeException("failed to freeze device orientation", e);
+        }
+        mIsV2EnabledByDefault = mHelper.getStringSetting(SettingsType.GLOBAL,
+                "settings_zone_picker_v2");
+        mHelper.setStringSetting(SettingsType.GLOBAL, "settings_zone_picker_v2", "true");
+        mIsAutoZoneEnabled = mHelper.getIntSetting(SettingsType.GLOBAL,
+                Settings.Global.AUTO_TIME_ZONE);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // Go back to home for next test.
+        mDevice.pressBack();
+        mDevice.pressBack();
+        mDevice.pressHome();
+        mDevice.waitForIdle(TIMEOUT * 2);
+        mHelper.setStringSetting(SettingsType.GLOBAL, "settings_zone_picker_v2",
+                mIsV2EnabledByDefault);
+        mHelper.setIntSetting(SettingsType.GLOBAL, Settings.Global.AUTO_TIME_ZONE,
+                mIsAutoZoneEnabled);
+    }
+
+    @Test
+    public void zonePickerDisabled() throws Exception {
+        mHelper.setIntSetting(SettingsType.GLOBAL, Settings.Global.AUTO_TIME_ZONE, 1);
+
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getContext(), Settings.ACTION_DATE_SETTINGS);
+        UiObject2 selectTimeZone = wait(SELECTOR_SELECT_TIME_ZONE);
+        assertFalse(selectTimeZone.isEnabled());
+    }
+
+    // Test 2 time zones with no DST
+    @Test
+    public void testSelectReykjavik() throws Exception {
+        testSelectTimeZone("Iceland", "Reykjavik", "GMT+00:00", "Atlantic/Reykjavik");
+    }
+
+    @Test
+    public void testSelectPhoenix() throws Exception {
+        testSelectTimeZone("United States", "Phoenix", "GMT-07:00", "America/Phoenix");
+    }
+
+    private void testSelectTimeZone(String region, String timezone, String expectedTimeZoneOffset,
+            String expectedTimeZoneId) throws Exception {
+        mHelper.setIntSetting(SettingsType.GLOBAL, Settings.Global.AUTO_TIME_ZONE, 0);
+
+        SettingsHelper.launchSettingsPage(
+                InstrumentationRegistry.getContext(), Settings.ACTION_DATE_SETTINGS);
+
+        UiObject2 selectTimeZone = wait(SELECTOR_SELECT_TIME_ZONE);
+        assertTrue(selectTimeZone.isEnabled());
+        selectTimeZone.click();
+
+        // Select region in the dropdown list
+        selectScrollableItem(selectDropDownInSpinner(By.clazz(Spinner.class)),
+                new UiSelector().textContains(region))
+                .click();
+
+        // Select time zone
+        selectScrollableItem(selectTimeZoneList(),
+                new UiSelector().textContains(timezone))
+                .click();
+
+        // The select button should include the GMT offset in the summary
+        BySelector summarySelector = By.res("android:id/summary");
+        UiObject2 selectedTimeZone = selectTimeZone.findObject(summarySelector);
+        assertUiObjectFound(selectedTimeZone, summarySelector);
+        assertTrue("Expect " + expectedTimeZoneOffset + " is shown for " + timezone,
+                selectedTimeZone.getText().startsWith(expectedTimeZoneOffset));
+
+        waitAndAssertTimeGetDefault(expectedTimeZoneId);
+        assertEquals("Time zone change in Settings should update persist.sys.timezone",
+                expectedTimeZoneId, SystemProperties.get("persist.sys.timezone"));
+    }
+
+    private static final long CHECK_DEFAULT_TIMEZONE_INTERVAL = 200L;
+    private static final long CHECK_DEFAULT_TIMEZONE_TIMEOUT = 3000L;
+
+    /**
+     * Wait for the broadcast ACTION_TIMEZONE_CHANGED propagated, and update the default TimeZone
+     * by ApplicationThread.
+     */
+    private static void waitAndAssertTimeGetDefault(String expectedTimeZoneId)
+            throws InterruptedException {
+        for (int i = 0; i < CHECK_DEFAULT_TIMEZONE_TIMEOUT / CHECK_DEFAULT_TIMEZONE_INTERVAL; i++) {
+            if (expectedTimeZoneId.equals(TimeZone.getDefault().getID())) {
+                return;
+            }
+            Thread.sleep(CHECK_DEFAULT_TIMEZONE_INTERVAL);
+        }
+
+        assertEquals(expectedTimeZoneId, TimeZone.getDefault().getID());
+    }
+
+    /**
+     * Perform click on {@link Spinner} and return the pop-up dropdown list.
+     * @return UiScrollable representing the pop-up dropdown after clicking on the spinner
+     */
+    private UiScrollable selectDropDownInSpinner(BySelector spinnerSelector)
+            throws UiObjectNotFoundException {
+        UiObject2 spinner = wait(spinnerSelector);
+        spinner.click();
+
+        UiSelector dropDownSelector = new UiSelector().className(ListView.class);
+        return new UiScrollable(dropDownSelector);
+    }
+
+    private UiScrollable selectTimeZoneList() {
+        return new UiScrollable(new UiSelector().resourceId(SETTINGS_PACKAGE + ":id/tz_list"));
+    }
+
+    /**
+     * Select the child object in the UiScrollable
+     * @throws UiObjectNotFoundException if scrollable or child is not found
+     */
+    private UiObject selectScrollableItem(UiScrollable scrollable, UiSelector childSelector)
+            throws UiObjectNotFoundException {
+        if (!scrollable.waitForExists(TIMEOUT)) {
+            throw newUiObjectNotFoundException(scrollable.getSelector());
+        }
+        scrollable.scrollIntoView(childSelector);
+
+        UiObject child = mDevice.findObject(childSelector);
+        assertUiObjectFound(child, childSelector);
+        return child;
+    }
+
+    /**
+     * @throws UiObjectNotFoundException if UiDevice.wait returns null
+     */
+    private UiObject2 wait(BySelector selector) throws UiObjectNotFoundException {
+        UiObject2 item = mDevice.wait(Until.findObject(selector), TIMEOUT);
+        assertUiObjectFound(item, selector);
+        return item;
+    }
+
+    private static void assertUiObjectFound(UiObject2 obj, BySelector selector)
+            throws UiObjectNotFoundException {
+        if (obj == null) {
+            throw newUiObjectNotFoundException(selector);
+        }
+    }
+
+
+    private static void assertUiObjectFound(UiObject obj, UiSelector selector)
+            throws UiObjectNotFoundException {
+        if (obj == null) {
+            throw newUiObjectNotFoundException(selector);
+        }
+    }
+
+    private static UiObjectNotFoundException newUiObjectNotFoundException(Object selector) {
+        return new UiObjectNotFoundException(
+                String.format("UI object not found: %s", selector.toString()));
+    }
+}
