1 /*
2  * Copyright (C) 2022 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 androidx.core.i18n;
18 
19 import static org.junit.Assert.assertEquals;
20 
21 import android.content.Context;
22 import android.os.Build;
23 
24 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Day;
25 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Era;
26 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.FractionalSecond;
27 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Hour;
28 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Minute;
29 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Month;
30 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Period;
31 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Second;
32 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Timezone;
33 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.WeekDay;
34 import androidx.core.i18n.DateTimeFormatterSkeletonOptions.Year;
35 import androidx.test.ext.junit.runners.AndroidJUnit4;
36 import androidx.test.filters.SmallTest;
37 import androidx.test.platform.app.InstrumentationRegistry;
38 
39 import org.junit.After;
40 import org.junit.Before;
41 import org.junit.BeforeClass;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 
45 import java.text.DateFormat;
46 import java.util.Calendar;
47 import java.util.Locale;
48 import java.util.TimeZone;
49 
50 /**
51  * This is less about testing and more to give us a feeling on how it is to use the APIs.
52  */
53 @RunWith(AndroidJUnit4.class)
54 public class CheckTheJavaApisTest {
55     private static TimeZone sSavedTimeZone;
56     private final Context mAppContext =
57             InstrumentationRegistry.getInstrumentation().getTargetContext();
58     private final Locale mLocale = Locale.GERMANY;
59     private final Calendar mCal =
60             Calendar.getInstance(TimeZone.getTimeZone("Europe/Paris"), mLocale);
61     {
62         mCal.set(2021, Calendar.AUGUST, 23, 19, 53, 47);
mCal.set(Calendar.MILLISECOND, 123)63         mCal.set(Calendar.MILLISECOND, 123);
64     }
65 
66     @BeforeClass
beforeClass()67     public static void beforeClass() {
68         sSavedTimeZone = TimeZone.getDefault();
69     }
70 
71     @Before
beforeTest()72     public void beforeTest() {
73         // Some of the test check that the functionality honors the default timezone.
74         // So we make sure it is set to something we control.
75         TimeZone tzLosAngeles = TimeZone.getTimeZone("America/Los_Angeles");
76         TimeZone.setDefault(tzLosAngeles);
77     }
78 
79     @After
afterTest()80     public void afterTest() {
81         if (sSavedTimeZone != null) {
82             TimeZone.setDefault(sSavedTimeZone);
83         }
84     }
85 
86     @Test @SmallTest
testSkeletonOptions()87     public void testSkeletonOptions() {
88         final DateTimeFormatterSkeletonOptions.Builder builder =
89                 new DateTimeFormatterSkeletonOptions.Builder()
90                         .setYear(Year.NUMERIC)
91                         .setMonth(Month.WIDE)
92                         .setDay(Day.NUMERIC)
93                         .setWeekDay(WeekDay.ABBREVIATED)
94                         .setHour(Hour.NUMERIC)
95                         .setMinute(Minute.NUMERIC)
96                         .setSecond(Second.NUMERIC)
97                         .setFractionalSecond(FractionalSecond.NUMERIC_3_DIGITS)
98                         .setEra(Era.ABBREVIATED)
99                         .setTimezone(Timezone.SHORT_GENERIC)
100                         .setPeriod(Period.FLEXIBLE);
101 
102         DateTimeFormatterSkeletonOptions dateTimeFormatterOptions = builder.build();
103         String expected;
104         if (Build.VERSION.SDK_INT >= 34) {
105             expected = "Mo., 23. August 2021 n. Chr. um 19:53:47,123 MEZ";
106         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
107             expected = "Mo., 23. August 2021 n. Chr., 19:53:47,123 MEZ";
108         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
109             expected = "Mo., 23. August 2021 n. Chr., 10:53:47,123 GMT-07:00";
110         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
111             expected = "Mo., 23. August 2021 n. Chr. 10:53:47,123 GMT-07:00";
112         } else {
113             expected = "Mo., 23. August 2021 n. Chr. 10:53:47,123 PDT";
114         }
115         // TODO: Bug? The hour is very different below M, as if the timezone is not supported.
116         // 19 vs 10 is Paris vs California time
117 
118         DateTimeFormatter df =
119                 new DateTimeFormatter(mAppContext, dateTimeFormatterOptions, mLocale);
120         assertEquals(expected, df.format(mCal));
121         assertEquals(
122                 expected,
123                 new DateTimeFormatter(mAppContext, dateTimeFormatterOptions, mLocale).format(mCal));
124 
125         // Verify DateTimeFormatterSkeletonOptions.fromString
126         dateTimeFormatterOptions = DateTimeFormatterSkeletonOptions.fromString("yMMMdjms");
127         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
128             expected = "23. Aug. 2021, 19:53:47";
129         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
130             expected = "23. Aug. 2021, 10:53:47";
131         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
132             expected = "23. Aug. 2021 10:53:47";
133         } else {
134             expected = "23. Aug. 2021 10:53:47";
135         }
136         df = new DateTimeFormatter(mAppContext, dateTimeFormatterOptions, mLocale);
137         assertEquals(expected, df.format(mCal));
138         assertEquals(
139                 expected,
140                 new DateTimeFormatter(mAppContext, dateTimeFormatterOptions, mLocale).format(mCal));
141 
142         // Verify DateTimeFormatterSkeletonOptions.fromString
143         dateTimeFormatterOptions = DateTimeFormatterSkeletonOptions.fromString("yMMMMdjmsEEEE");
144         if (Build.VERSION.SDK_INT >= 34) {
145             expected = "Montag, 23. August 2021 um 19:53:47";
146         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
147             expected = "Montag, 23. August 2021, 19:53:47";
148         } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
149             expected = "Montag, 23. August 2021, 10:53:47";
150         } else {
151             expected = "Montag, 23. August 2021 10:53:47";
152         }
153         df = new DateTimeFormatter(mAppContext, dateTimeFormatterOptions, mLocale);
154         assertEquals(expected, df.format(mCal));
155         assertEquals(
156                 expected,
157                 new DateTimeFormatter(mAppContext, dateTimeFormatterOptions, mLocale).format(mCal));
158     }
159 
160     @Test @SmallTest
testJdkOptions()161     public void testJdkOptions() {
162         DateTimeFormatterJdkStyleOptions options =
163                 DateTimeFormatterJdkStyleOptions.createDateInstance(DateFormat.LONG);
164         assertEquals("23. August 2021",
165                 new DateTimeFormatter(options, mLocale).format(mCal));
166     }
167 }
168