1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.util.cts;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNull;
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.fail;
22 
23 import android.util.TimeUtils;
24 
25 import androidx.test.filters.SmallTest;
26 import androidx.test.runner.AndroidJUnit4;
27 
28 import org.junit.Test;
29 import org.junit.runner.RunWith;
30 
31 import java.util.Calendar;
32 import java.util.Collection;
33 import java.util.List;
34 import java.util.TimeZone;
35 
36 @SmallTest
37 @RunWith(AndroidJUnit4.class)
38 public class TimeUtilsTest {
39     @Test
testUnitedStates()40     public void testUnitedStates() throws Exception {
41         String[] mainstream = new String[] {
42             "America/New_York", // Eastern
43             "America/Chicago", // Central
44             "America/Denver", // Mountain
45             "America/Los_Angeles", // Pacific
46             "America/Anchorage", // Alaska
47             "Pacific/Honolulu", // Hawaii, no DST
48         };
49 
50         for (String name : mainstream) {
51             TimeZone tz = TimeZone.getTimeZone(name);
52             Calendar c = Calendar.getInstance(tz);
53             TimeZone guess;
54 
55             c.set(2016, Calendar.OCTOBER, 20, 12, 0, 0);
56             guess = guessTimeZone(c, "us");
57             assertEquals(name, guess.getID());
58 
59             c.set(2017, Calendar.JANUARY, 20, 12, 0, 0);
60             guess = guessTimeZone(c, "us");
61             assertEquals(name, guess.getID());
62         }
63     }
64 
65     @Test
testWeirdUnitedStates()66     public void testWeirdUnitedStates() throws Exception {
67         String[] weird = new String[] {
68             "America/Phoenix", // Mountain, no DST
69             "America/Adak", // Same as Hawaii, but with DST
70         };
71 
72         for (String name : weird) {
73             TimeZone tz = TimeZone.getTimeZone(name);
74             Calendar c = Calendar.getInstance(tz);
75             TimeZone guess;
76 
77             c.set(2016, Calendar.OCTOBER, 20, 12, 0, 0);
78             guess = guessTimeZone(c, "us");
79             assertEquals(name, guess.getID());
80         }
81     }
82 
83     @Test
testOld()84     public void testOld() throws Exception {
85         String[] old = new String[] {
86             "America/Indiana/Indianapolis", // Eastern, formerly no DST
87         };
88 
89         for (String name : old) {
90             TimeZone tz = TimeZone.getTimeZone(name);
91             Calendar c = Calendar.getInstance(tz);
92             TimeZone guess;
93 
94             c.set(2005, Calendar.OCTOBER, 20, 12, 0, 0);
95             guess = guessTimeZone(c, "us");
96             assertEquals(name, guess.getID());
97         }
98     }
99 
100     @Test
testWorldWeird()101     public void testWorldWeird() throws Exception {
102         String[] world = new String[] {
103             // Distinguisable from Sydney only when DST not in effect
104             "au", "Australia/Lord_Howe",
105         };
106 
107         for (int i = 0; i < world.length; i += 2) {
108             String country = world[i];
109             String name = world[i + 1];
110 
111             TimeZone tz = TimeZone.getTimeZone(name);
112             Calendar c = Calendar.getInstance(tz);
113             TimeZone guess;
114 
115             c.set(2016, Calendar.JULY, 20, 12, 0, 0);
116             guess = guessTimeZone(c, country);
117             assertEquals(name, guess.getID());
118         }
119     }
120 
guessTimeZone(Calendar c, String country)121     private static TimeZone guessTimeZone(Calendar c, String country) {
122         return TimeUtils.getTimeZone(c.get(Calendar.ZONE_OFFSET) + c.get(Calendar.DST_OFFSET),
123                                      c.get(Calendar.DST_OFFSET) != 0,
124                                      c.getTimeInMillis(),
125                                      country);
126     }
127 
128     @Test
testFormatDuration()129     public void testFormatDuration() {
130         assertFormatDuration("0", 0);
131         assertFormatDuration("-1ms", -1);
132         assertFormatDuration("+1ms", 1);
133         assertFormatDuration("+10ms", 10);
134         assertFormatDuration("+100ms", 100);
135         assertFormatDuration("+101ms", 101);
136         assertFormatDuration("+330ms", 330);
137         assertFormatDuration("+1s0ms", 1000);
138         assertFormatDuration("+1s330ms", 1330);
139         assertFormatDuration("+10s24ms", 10024);
140         assertFormatDuration("+1m0s30ms", 60030);
141         assertFormatDuration("+1h0m0s30ms", 3600030);
142         assertFormatDuration("+1d0h0m0s30ms", 86400030);
143     }
144 
145     @Test
testFormatHugeDuration()146     public void testFormatHugeDuration() {
147         assertFormatDuration("+15542d1h11m11s555ms", 1342833071555L);
148         assertFormatDuration("-15542d1h11m11s555ms", -1342833071555L);
149     }
150 
assertFormatDuration(String expected, long duration)151     private static void assertFormatDuration(String expected, long duration) {
152         StringBuilder sb = new StringBuilder();
153         TimeUtils.formatDuration(duration, sb);
154         assertEquals("formatDuration(" + duration + ")", expected, sb.toString());
155     }
156 
157     @Test
testGetTimeZoneIdsForCountryCode()158     public void testGetTimeZoneIdsForCountryCode() {
159         List<String> usTimeZones = TimeUtils.getTimeZoneIdsForCountryCode("us");
160 
161         // Sample the content without being too exact.
162         assertCollectionContains(usTimeZones, "America/Los_Angeles");
163         assertCollectionContains(usTimeZones, "America/New_York");
164 
165         // Assert we don't care about casing of the country code.
166         assertEquals(usTimeZones, TimeUtils.getTimeZoneIdsForCountryCode("US"));
167         assertEquals(usTimeZones, TimeUtils.getTimeZoneIdsForCountryCode("uS"));
168         assertEquals(usTimeZones, TimeUtils.getTimeZoneIdsForCountryCode("Us"));
169     }
170 
171     @Test
testGetTimeZoneIdsForCountryCode_unknownCountryCode()172     public void testGetTimeZoneIdsForCountryCode_unknownCountryCode() {
173         String unknownCountryCode = "zx81";
174         assertNull(TimeUtils.getTimeZoneIdsForCountryCode(unknownCountryCode));
175     }
176 
177     @Test
testGetTimeZoneIdsForCountryCode_nullCountryCode()178     public void testGetTimeZoneIdsForCountryCode_nullCountryCode() {
179         try {
180             TimeUtils.getTimeZoneIdsForCountryCode(null);
181             fail();
182         } catch (NullPointerException expected) {
183         }
184     }
185 
assertCollectionContains(Collection<? super T> collection, T value)186     private static <T> void assertCollectionContains(Collection<? super T> collection, T value) {
187         assertTrue(collection + " should contain " + value, collection.contains(value));
188     }
189 }
190