| /* |
| * Copyright (C) 2019 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 android.text.format; |
| |
| import static org.junit.Assert.assertEquals; |
| |
| import android.platform.test.annotations.Presubmit; |
| |
| import androidx.test.filters.SmallTest; |
| import androidx.test.runner.AndroidJUnit4; |
| |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.util.Locale; |
| import java.util.TimeZone; |
| |
| @Presubmit |
| @SmallTest |
| @RunWith(AndroidJUnit4.class) |
| public class TimeMigrationUtilsTest { |
| |
| private static final int ONE_DAY_IN_SECONDS = 24 * 60 * 60; |
| |
| private Locale mDefaultLocale; |
| private TimeZone mDefaultTimeZone; |
| |
| @Before |
| public void setUp() { |
| mDefaultLocale = Locale.getDefault(); |
| mDefaultTimeZone = TimeZone.getDefault(); |
| } |
| |
| @After |
| public void tearDown() { |
| Locale.setDefault(mDefaultLocale); |
| TimeZone.setDefault(mDefaultTimeZone); |
| } |
| |
| @Test |
| public void formatMillisWithFixedFormat_fixes2038Issue() { |
| Locale.setDefault(Locale.UK); |
| TimeZone.setDefault(TimeZone.getTimeZone("UTC")); |
| |
| // The following cannot be represented properly using Time because they are outside of the |
| // supported range. |
| long y2038Issue1 = (((long) Integer.MIN_VALUE) - ONE_DAY_IN_SECONDS) * 1000L; |
| assertEquals( |
| "1901-12-12 20:45:52", TimeMigrationUtils.formatMillisWithFixedFormat(y2038Issue1)); |
| long y2038Issue2 = (((long) Integer.MAX_VALUE) + ONE_DAY_IN_SECONDS) * 1000L; |
| assertEquals( |
| "2038-01-20 03:14:07", TimeMigrationUtils.formatMillisWithFixedFormat(y2038Issue2)); |
| } |
| |
| /** |
| * Compares TimeMigrationUtils.formatSimpleDateTime() with the code it is replacing. |
| */ |
| @Test |
| public void formatMillisAsDateTime_matchesOldBehavior() { |
| // A selection of interesting locales. |
| Locale[] locales = new Locale[] { |
| Locale.US, |
| Locale.UK, |
| Locale.FRANCE, |
| Locale.JAPAN, |
| Locale.CHINA, |
| // Android supports RTL locales like arabic and arabic with latin numbers. |
| Locale.forLanguageTag("ar-AE"), |
| Locale.forLanguageTag("ar-AE-u-nu-latn"), |
| }; |
| // A selection of interesting time zones. |
| String[] timeZoneIds = new String[] { |
| "UTC", "Europe/London", "America/New_York", "America/Los_Angeles", "Asia/Shanghai", |
| }; |
| // Some arbitrary times when the two formatters should agree. |
| long[] timesMillis = new long[] { |
| System.currentTimeMillis(), |
| 0, |
| // The Time class only works in 32-bit range, the replacement works beyond that. To |
| // avoid messing around with offsets and complicating the test, below there are a |
| // day after / before the known limits. |
| (Integer.MIN_VALUE + ONE_DAY_IN_SECONDS) * 1000L, |
| (Integer.MAX_VALUE - ONE_DAY_IN_SECONDS) * 1000L, |
| }; |
| |
| for (Locale locale : locales) { |
| Locale.setDefault(locale); |
| for (String timeZoneId : timeZoneIds) { |
| TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); |
| TimeZone.setDefault(timeZone); |
| for (long timeMillis : timesMillis) { |
| Time time = new Time(); |
| time.set(timeMillis); |
| String oldResult = time.format("%Y-%m-%d %H:%M:%S"); |
| String newResult = TimeMigrationUtils.formatMillisWithFixedFormat(timeMillis); |
| assertEquals( |
| "locale=" + locale + ", timeZoneId=" + timeZoneId |
| + ", timeMillis=" + timeMillis, |
| oldResult, newResult); |
| } |
| } |
| } |
| } |
| } |