NitzDataTest.java revision d8ce837499725b7eac7c5405d8fbf6c7cc27b774
1/*
2 * Copyright 2017 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
17package com.android.internal.telephony;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertNotNull;
21import static org.junit.Assert.assertNull;
22
23import org.junit.Test;
24
25import java.util.Calendar;
26import java.util.Date;
27import java.util.GregorianCalendar;
28import java.util.TimeZone;
29import java.util.concurrent.TimeUnit;
30
31public class NitzDataTest {
32
33    @Test
34    public void testParse_dateOutsideAllowedRange() {
35        assertNull(NitzData.parse("38/06/20,00:00:00+0"));
36    }
37
38    @Test
39    public void testParse_missingRequiredFields() {
40        // "yy/mm/dd,hh:mm:ss(+/-)tz[,dt[,tzid]]"
41
42        // No tz field.
43        assertNull(NitzData.parse("38/06/20,00:00:00"));
44    }
45
46    @Test
47    public void testParse_withDst() {
48        // "yy/mm/dd,hh:mm:ss(+/-)tz[,dt[,tzid]]"
49        // tz, dt are in number of quarter-hours
50        {
51            NitzData nitz = NitzData.parse("15/06/20,01:02:03-1,0");
52            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
53            assertEquals(TimeUnit.MINUTES.toMillis(-1 * 15), nitz.getLocalOffsetMillis());
54            assertEquals(0, nitz.getDstAdjustmentMillis().longValue());
55            assertNull(nitz.getEmulatorHostTimeZone());
56        }
57        {
58            NitzData nitz = NitzData.parse("15/06/20,01:02:03+8,4");
59            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
60            assertEquals(TimeUnit.MINUTES.toMillis(8 * 15), nitz.getLocalOffsetMillis());
61            assertEquals(TimeUnit.MINUTES.toMillis(4 * 15),
62                    nitz.getDstAdjustmentMillis().longValue());
63            assertNull(nitz.getEmulatorHostTimeZone());
64        }
65        {
66            NitzData nitz = NitzData.parse("15/06/20,01:02:03-8,4");
67            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
68            assertEquals(TimeUnit.MINUTES.toMillis(-8 * 15), nitz.getLocalOffsetMillis());
69            assertEquals(TimeUnit.MINUTES.toMillis(4 * 15),
70                    nitz.getDstAdjustmentMillis().longValue());
71            assertNull(nitz.getEmulatorHostTimeZone());
72        }
73    }
74
75    @Test
76    public void testParse_noDstField() {
77        {
78            NitzData nitz = NitzData.parse("15/06/20,01:02:03+4");
79            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
80            assertEquals(TimeUnit.MINUTES.toMillis(4 * 15), nitz.getLocalOffsetMillis());
81            assertNull(nitz.getDstAdjustmentMillis());
82            assertNull(nitz.getEmulatorHostTimeZone());
83        }
84        {
85            NitzData nitz = NitzData.parse("15/06/20,01:02:03-4");
86            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
87            assertEquals(TimeUnit.MINUTES.toMillis(-4 * 15), nitz.getLocalOffsetMillis());
88            assertNull(nitz.getDstAdjustmentMillis());
89            assertNull(nitz.getEmulatorHostTimeZone());
90        }
91    }
92
93    @Test
94    public void testParse_androidEmulatorTimeZoneExtension() {
95        NitzData nitz = NitzData.parse("15/06/20,01:02:03-32,4,America!Los_Angeles");
96        assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
97        assertEquals(TimeUnit.MINUTES.toMillis(-32 * 15), nitz.getLocalOffsetMillis());
98        assertEquals(TimeUnit.MINUTES.toMillis(4 * 15),
99                nitz.getDstAdjustmentMillis().longValue());
100        assertEquals("America/Los_Angeles", nitz.getEmulatorHostTimeZone().getID());
101    }
102
103    @Test
104    public void testToString() {
105        assertNotNull(NitzData.parse("15/06/20,01:02:03-32").toString());
106        assertNotNull(NitzData.parse("15/06/20,01:02:03-32,4").toString());
107        assertNotNull(NitzData.parse("15/06/20,01:02:03-32,4,America!Los_Angeles")
108                .toString());
109    }
110
111    @Test
112    public void testGuessTimeZone() {
113        // Historical dates are used to avoid the test breaking due to data changes.
114        // However, algorithm updates may change the exact time zone returned, though it shouldn't
115        // ever be a less exact match.
116        long nhSummerTimeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
117        long nhWinterTimeMillis = createUtcTime(2015, 1, 20, 1, 2, 3);
118        String nhSummerTimeString = "15/06/20,01:02:03";
119        String nhWinterTimeString = "15/01/20,01:02:03";
120
121        // Known DST state (true).
122        assertTimeZone(nhSummerTimeMillis, TimeUnit.HOURS.toMillis(1), TimeUnit.HOURS.toMillis(1),
123                NitzData.guessTimeZone(NitzData.parse(nhSummerTimeString + "+4,4")));
124        assertTimeZone(nhSummerTimeMillis, TimeUnit.HOURS.toMillis(-8), TimeUnit.HOURS.toMillis(1),
125                NitzData.guessTimeZone(NitzData.parse("15/06/20,01:02:03-32,4")));
126
127        // Known DST state (false)
128        assertTimeZone(nhWinterTimeMillis, 0L, 0L,
129                NitzData.guessTimeZone(NitzData.parse(nhWinterTimeString + "+0,0")));
130        assertTimeZone(nhWinterTimeMillis, TimeUnit.HOURS.toMillis(-8), 0L,
131                NitzData.guessTimeZone(NitzData.parse(nhWinterTimeString + "-32,0")));
132
133        // Unknown DST state
134        assertTimeZone(nhSummerTimeMillis, TimeUnit.HOURS.toMillis(1), null,
135                NitzData.guessTimeZone(NitzData.parse(nhSummerTimeString + "+4")));
136        assertTimeZone(nhSummerTimeMillis, TimeUnit.HOURS.toMillis(-8), null,
137                NitzData.guessTimeZone(NitzData.parse(nhSummerTimeString + "-32")));
138        assertTimeZone(nhWinterTimeMillis, 0L, null,
139                NitzData.guessTimeZone(NitzData.parse(nhWinterTimeString + "+0")));
140        assertTimeZone(nhWinterTimeMillis, TimeUnit.HOURS.toMillis(-8), null,
141                NitzData.guessTimeZone(NitzData.parse(nhWinterTimeString + "-32")));
142    }
143
144    private static void assertTimeZone(
145            long time, long expectedOffsetAtTime, Long expectedDstAtTime, TimeZone timeZone) {
146
147        GregorianCalendar calendar = new GregorianCalendar(timeZone);
148        calendar.setTimeInMillis(time);
149        int actualOffsetAtTime =
150                calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET);
151        assertEquals(expectedOffsetAtTime, actualOffsetAtTime);
152
153        if (expectedDstAtTime != null) {
154            Date date = new Date(time);
155            assertEquals(expectedDstAtTime > 0, timeZone.inDaylightTime(date));
156
157            // The code under test assumes DST means +1 in all cases,
158            // This code makes fewer assumptions.
159            assertEquals(expectedDstAtTime.intValue(), calendar.get(Calendar.DST_OFFSET));
160        }
161    }
162
163    private static long createUtcTime(
164            int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minute, int second) {
165        GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
166        calendar.clear(); // Clear millis, etc.
167        calendar.set(year, monthOfYear - 1, dayOfMonth, hourOfDay, minute, second);
168        return calendar.getTimeInMillis();
169    }
170}
171