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 17 package android.text.format.cts; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertSame; 23 import static org.junit.Assert.assertTrue; 24 25 import android.content.Context; 26 import android.text.format.DateUtils; 27 28 import androidx.test.InstrumentationRegistry; 29 import androidx.test.filters.SmallTest; 30 import androidx.test.runner.AndroidJUnit4; 31 32 import org.junit.After; 33 import org.junit.Before; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 37 import java.util.Calendar; 38 import java.util.Date; 39 import java.util.Formatter; 40 import java.util.GregorianCalendar; 41 import java.util.Locale; 42 import java.util.TimeZone; 43 44 @SmallTest 45 @RunWith(AndroidJUnit4.class) 46 public class DateUtilsTest { 47 private TimeZone mDefaultTimeZone; 48 private long mBaseTime; 49 private Context mContext; 50 51 @Before setup()52 public void setup() { 53 mContext = InstrumentationRegistry.getTargetContext(); 54 mDefaultTimeZone = TimeZone.getDefault(); 55 // All tests in this class can assume the device time zone is set to GMT. 56 TimeZone.setDefault(TimeZone.getTimeZone("GMT")); 57 mBaseTime = System.currentTimeMillis(); 58 } 59 60 @After tearDown()61 public void tearDown() { 62 // Set the default time zone back to what it was before setup(). 63 TimeZone.setDefault(mDefaultTimeZone); 64 } 65 66 @Test testGetDayOfWeekString()67 public void testGetDayOfWeekString() { 68 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 69 return; 70 } 71 72 assertEquals("Sunday", 73 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_LONG)); 74 assertEquals("Sun", 75 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_MEDIUM)); 76 assertEquals("Sun", 77 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORT)); 78 assertEquals("Sun", 79 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORTER)); 80 assertEquals("S", 81 DateUtils.getDayOfWeekString(Calendar.SUNDAY, DateUtils.LENGTH_SHORTEST)); 82 // Other abbrev 83 assertEquals("Sun", 84 DateUtils.getDayOfWeekString(Calendar.SUNDAY, 60)); 85 } 86 87 @Test testGetMonthString()88 public void testGetMonthString() { 89 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 90 return; 91 } 92 assertEquals("January", DateUtils.getMonthString(Calendar.JANUARY, DateUtils.LENGTH_LONG)); 93 assertEquals("Jan", 94 DateUtils.getMonthString(Calendar.JANUARY, DateUtils.LENGTH_MEDIUM)); 95 assertEquals("Jan", DateUtils.getMonthString(Calendar.JANUARY, DateUtils.LENGTH_SHORT)); 96 assertEquals("Jan", 97 DateUtils.getMonthString(Calendar.JANUARY, DateUtils.LENGTH_SHORTER)); 98 assertEquals("J", 99 DateUtils.getMonthString(Calendar.JANUARY, DateUtils.LENGTH_SHORTEST)); 100 // Other abbrev 101 assertEquals("Jan", DateUtils.getMonthString(Calendar.JANUARY, 60)); 102 } 103 104 @Test testGetAMPMString()105 public void testGetAMPMString() { 106 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 107 return; 108 } 109 assertEquals("AM", DateUtils.getAMPMString(Calendar.AM)); 110 assertEquals("PM", DateUtils.getAMPMString(Calendar.PM)); 111 } 112 113 // This is to test the mapping between DateUtils' public API and 114 // libcore/icu4c's implementation. More tests, in different locales, are 115 // in libcore's CTS tests. 116 @Test test_getRelativeTimeSpanString()117 public void test_getRelativeTimeSpanString() { 118 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 119 return; 120 } 121 122 final long ONE_SECOND_IN_MS = 1000; 123 assertEquals("0 minutes ago", 124 DateUtils.getRelativeTimeSpanString(mBaseTime - ONE_SECOND_IN_MS)); 125 assertEquals("In 0 minutes", 126 DateUtils.getRelativeTimeSpanString(mBaseTime + ONE_SECOND_IN_MS)); 127 128 final long ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS; 129 assertEquals("1 minute ago", DateUtils.getRelativeTimeSpanString(0, ONE_MINUTE_IN_MS, 130 DateUtils.MINUTE_IN_MILLIS)); 131 assertEquals("In 1 minute", DateUtils.getRelativeTimeSpanString(ONE_MINUTE_IN_MS, 0, 132 DateUtils.MINUTE_IN_MILLIS)); 133 134 final long ONE_HOUR_IN_MS = 60 * 60 * 1000; 135 final long TWO_HOURS_IN_MS = 2 * ONE_HOUR_IN_MS; 136 assertEquals("2 hours ago", DateUtils.getRelativeTimeSpanString(mBaseTime - TWO_HOURS_IN_MS, 137 mBaseTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_NUMERIC_DATE)); 138 assertEquals("In 2 hours", DateUtils.getRelativeTimeSpanString(mBaseTime + TWO_HOURS_IN_MS, 139 mBaseTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_NUMERIC_DATE)); 140 } 141 142 @Test test_getRelativeTimeSpanString_withContext()143 public void test_getRelativeTimeSpanString_withContext() { 144 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 145 return; 146 } 147 148 final GregorianCalendar cal = new GregorianCalendar(); 149 cal.setTimeInMillis(mBaseTime); 150 cal.set(Calendar.HOUR_OF_DAY, 10); 151 cal.set(Calendar.MINUTE, 0); 152 final long today10am = cal.getTimeInMillis(); 153 154 final CharSequence withPrep = DateUtils.getRelativeTimeSpanString(mContext, today10am, 155 true /* with preposition */); 156 final CharSequence noPrep = DateUtils.getRelativeTimeSpanString(mContext, today10am, 157 false /* no preposition */); 158 assertEquals(noPrep, DateUtils.getRelativeTimeSpanString(mContext, today10am)); 159 160 if (android.text.format.DateFormat.is24HourFormat(mContext)) { 161 assertEquals("at 10:00", withPrep); 162 assertEquals("10:00", noPrep); 163 } else { 164 assertEquals("at 10:00 AM", withPrep); 165 assertEquals("10:00 AM", noPrep); 166 } 167 } 168 169 // Similar to test_getRelativeTimeSpanString(). The function here is to 170 // test the mapping between DateUtils's public API and libcore/icu4c's 171 // implementation. More tests, in different locales, are in libcore's 172 // CTS tests. 173 @Test test_getRelativeDateTimeString()174 public void test_getRelativeDateTimeString() { 175 final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000; 176 assertNotNull(DateUtils.getRelativeDateTimeString(mContext, mBaseTime - DAY_DURATION, 177 DateUtils.MINUTE_IN_MILLIS, DateUtils.DAY_IN_MILLIS, DateUtils.FORMAT_NUMERIC_DATE)); 178 } 179 180 @Test test_formatElapsedTime()181 public void test_formatElapsedTime() { 182 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 183 return; 184 } 185 186 long MINUTES = 60; 187 long HOURS = 60 * MINUTES; 188 verifyFormatElapsedTime("02:01", 2 * MINUTES + 1); 189 verifyFormatElapsedTime("3:02:01", 3 * HOURS + 2 * MINUTES + 1); 190 // http://code.google.com/p/android/issues/detail?id=41401 191 verifyFormatElapsedTime("123:02:01", 123 * HOURS + 2 * MINUTES + 1); 192 } 193 verifyFormatElapsedTime(String expected, long elapsedTime)194 private void verifyFormatElapsedTime(String expected, long elapsedTime) { 195 assertEquals(expected, DateUtils.formatElapsedTime(elapsedTime)); 196 StringBuilder sb = new StringBuilder(); 197 assertEquals(expected, DateUtils.formatElapsedTime(sb, elapsedTime)); 198 assertEquals(expected, sb.toString()); 199 } 200 201 // This is just to exercise the wrapper that calls the libcore/icu4c implementation. 202 // Full testing, in multiple locales, is in libcore's CTS tests. 203 @Test testFormatDateRange()204 public void testFormatDateRange() { 205 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 206 return; 207 } 208 209 final Date date = new Date(109, 0, 19, 3, 30, 15); 210 final long fixedTime = date.getTime(); 211 final long hourDuration = 2 * 60 * 60 * 1000; 212 assertEquals("Monday", DateUtils.formatDateRange(mContext, fixedTime, 213 fixedTime + hourDuration, DateUtils.FORMAT_SHOW_WEEKDAY)); 214 } 215 216 @Test testFormatDateRange_withFormatter()217 public void testFormatDateRange_withFormatter() { 218 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 219 return; 220 } 221 222 final Date date = new Date(109, 0, 19, 3, 30, 15); 223 final long fixedTime = date.getTime(); 224 final long hourDuration = 2 * 60 * 60 * 1000; 225 final Formatter formatter = new Formatter(); 226 final Formatter result = DateUtils.formatDateRange(mContext, formatter, fixedTime, 227 fixedTime + hourDuration, DateUtils.FORMAT_SHOW_WEEKDAY); 228 assertEquals("Monday", result.toString()); 229 assertSame(result, formatter); 230 } 231 232 @Test testFormatDateRange_withFormatterAndTimezone()233 public void testFormatDateRange_withFormatterAndTimezone() { 234 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 235 return; 236 } 237 238 final Date date = new Date(109, 0, 19, 3, 30, 15); 239 final long fixedTime = date.getTime(); 240 final long hourDuration = 2 * 60 * 60 * 1000; 241 final Formatter formatter = new Formatter(); 242 final Formatter result = DateUtils.formatDateRange(mContext, formatter, fixedTime, 243 fixedTime + hourDuration, DateUtils.FORMAT_SHOW_WEEKDAY, null /* local */); 244 assertEquals("Monday", result.toString()); 245 assertSame(result, formatter); 246 } 247 248 @Test testFormatDateTime()249 public void testFormatDateTime() { 250 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 251 return; 252 } 253 254 final Date date = new Date(109, 0, 19, 3, 30, 15); 255 final long fixedTime = date.getTime(); 256 assertEquals("Monday", DateUtils.formatDateTime(mContext, fixedTime, 257 DateUtils.FORMAT_SHOW_WEEKDAY)); 258 } 259 260 @Test testIsToday()261 public void testIsToday() { 262 // This test assumes TimeZone.getDefault() returns GMT. See setup() and comments below for 263 // details. 264 265 final int ONE_HOUR_IN_MS = 60 * 60 * 1000; 266 final int ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS; 267 268 // mBaseTime < System.currentTimeMillis(), so subtracting 24 hours is guaranteed to 269 // be yesterday because this test uses GMT, i.e. no DST to consider. 270 assertFalse(DateUtils.isToday(mBaseTime - ONE_DAY_IN_MS)); 271 272 // We can assume mBaseTime is within a few seconds of the current system clock so adding 273 // one day plus one hour is more than sufficient to ensure isToday() == false. 274 assertFalse(DateUtils.isToday(mBaseTime + ONE_DAY_IN_MS + ONE_HOUR_IN_MS)); 275 276 // This assertion is flaky because the method under test uses the system clock. If mBaseTime 277 // is set just before midnight (GMT) and isToday() is run just after midnight (GMT), this 278 // assertion will fail. 279 assertTrue("mBaseTime=" + mBaseTime + ", System.currentTimeMillis() after failure=" 280 + System.currentTimeMillis(), DateUtils.isToday(mBaseTime)); 281 } 282 283 @Test test_bug_7548161()284 public void test_bug_7548161() { 285 if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) { 286 return; 287 } 288 289 long now = System.currentTimeMillis(); 290 long today = now; 291 long tomorrow = now + DateUtils.DAY_IN_MILLIS; 292 long yesterday = now - DateUtils.DAY_IN_MILLIS; 293 assertEquals("Tomorrow", DateUtils.getRelativeTimeSpanString(tomorrow, now, 294 DateUtils.DAY_IN_MILLIS, 0)); 295 assertEquals("Yesterday", DateUtils.getRelativeTimeSpanString(yesterday, now, 296 DateUtils.DAY_IN_MILLIS, 0)); 297 assertEquals("Today", DateUtils.getRelativeTimeSpanString(today, now, 298 DateUtils.DAY_IN_MILLIS, 0)); 299 } 300 } 301