1 /*
  2  * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */
 23 
 24 /*
 25  * @test
 26  * @bug 4860664 4916815 4867075
 27  * @library /java/text/testlib
 28  * @build Koyomi
 29  * @run main FieldStateTest
 30  * @summary Unit tests for internal fields states.
 31  */
 32 
 33 import java.util.Date;
 34 import java.util.Locale;
 35 import java.util.TimeZone;
 36 
 37 import static java.util.Calendar.*;
 38 
 39 public class FieldStateTest extends IntlTest {
 40 
 41     public static void main(String[] args) throws Exception {
 42         Locale reservedLocale = Locale.getDefault();
 43         TimeZone reservedTimeZone = TimeZone.getDefault();
 44         try {
 45             TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
 46             Locale.setDefault(Locale.US);
 47 
 48             new FieldStateTest().run(args);
 49         } finally {
 50             // restore the reserved locale and time zone
 51             Locale.setDefault(reservedLocale);
 52             TimeZone.setDefault(reservedTimeZone);
 53         }
 54     }
 55 
 56     public void TestFieldState() {
 57         Koyomi cal = new Koyomi();
 58         logln("Right after instantialtion:");
 59         if (!cal.checkAllSet()) {
 60             errln(cal.getMessage());
 61         }
 62 
 63         logln("Set date to 2003/10/31 after the instantiation:");
 64         cal.set(2003, OCTOBER, 31);
 65         // let cal calculate the time
 66         cal.getTime();
 67         // At this point, all fields have to be recalculated and
 68         // happen to have the set-state from the instantiation. The
 69         // three fields should have "externally set" and the rest of
 70         // the fields have "computed". But we can't distinguish them
 71         // outside the package.
 72         if (!cal.checkAllSet()) {
 73             errln(cal.getMessage());
 74         }
 75         // Make sure that the correct date was produced.
 76         if (!cal.checkInternalDate(2003, OCTOBER, 31, FRIDAY)) {
 77             errln(cal.getMessage());
 78         }
 79 
 80         logln("Change to Monday of the week, which is 2003/10/27:");
 81         cal.set(DAY_OF_WEEK, MONDAY);
 82         cal.getTime();
 83         if (!cal.checkDate(2003, OCTOBER, 27)) {
 84             errln(cal.getMessage());
 85         }
 86 
 87         // The same operation didn't work after calling clear() before
 88         // 1.5 because the set-state was just depends on its previous
 89         // operations. After the instantiation, all the fields are set
 90         // to "computed". But after calling clear(), the state becomes
 91         // "unset".
 92         logln("Set to 2003/10/31 after clear():");
 93         cal.clear();
 94         cal.set(2003, OCTOBER, 31);
 95         cal.getTime();
 96         cal.set(DAY_OF_WEEK, MONDAY);
 97         if (!cal.checkDate(2003, OCTOBER, 27, MONDAY)) {
 98             errln(cal.getMessage());
 99         }
100 
101         logln("Set to 2003/10/31 after clear(), then to the 51st week of year (12/19):");
102         cal.clear();
103         cal.set(2003, OCTOBER, 31);
104         cal.getTime();
105         cal.set(WEEK_OF_YEAR, 51);
106         if (!cal.checkFieldValue(WEEK_OF_YEAR, 51)) {
107             errln(cal.getMessage());
108         }
109         if (!cal.checkDate(2003, DECEMBER, 19, FRIDAY)) {
110             errln(cal.getMessage());
111         }
112 
113         logln("Set to 2003/10 Mon of 4th week (10/20: 43rd week of year, 293rd day):");
114         cal.clear();
115         cal.set(YEAR, 2003);
116         cal.set(MONTH, OCTOBER);
117         cal.set(DAY_OF_WEEK, MONDAY);
118         cal.set(WEEK_OF_MONTH, 4);
119         cal.getTime();
120         if (!cal.checkFieldValue(DAY_OF_MONTH, 20)) {
121             errln(cal.getMessage());
122         }
123         if (!cal.checkFieldValue(DAY_OF_YEAR, 293)) {
124             errln(cal.getMessage());
125         }
126         if (!cal.checkFieldValue(WEEK_OF_YEAR, 43)) {
127             errln(cal.getMessage());
128         }
129 
130         logln("Set to 2003/10 Mon of 43rd week of year (10/20: 4th week of month, 293rd day):");
131         cal.clear();
132         cal.set(YEAR, 2003);
133         cal.set(DAY_OF_WEEK, MONDAY);
134         cal.set(WEEK_OF_YEAR, 43);
135         cal.getTime();
136         if (!cal.checkDate(2003, OCTOBER, 20, MONDAY)) {
137             errln(cal.getMessage());
138         }
139         if (!cal.checkFieldValue(WEEK_OF_MONTH, 4)) {
140             errln(cal.getMessage());
141         }
142         if (!cal.checkFieldValue(DAY_OF_YEAR, 293)) {
143             errln(cal.getMessage());
144         }
145 
146         logln("Set day of week to SUNDAY and date to 2003/10/31. "
147                 + "Then, getTime and set week of year to 43.");
148 
149         @SuppressWarnings("deprecation")
150         Date d = new Date(2003 - 1900, OCTOBER, 31);
151         cal.setTime(d);
152         cal.set(DAY_OF_WEEK, SUNDAY);
153         cal.set(2003, OCTOBER, 31); // 2003/10/31 is Friday.
154         cal.set(ZONE_OFFSET, 0);
155         cal.set(DST_OFFSET, 0);
156 
157         // This call should change the day of week to FRIDAY since the
158         // selected field combination should be YEAR, MONTH and
159         // DAY_OF_MONTH. The other calendar fields must be normalized
160         // with the selected date.
161         cal.getTime();
162         cal.set(WEEK_OF_YEAR, 43);
163         if (!cal.checkDate(2003, OCTOBER, 24, FRIDAY)) {
164             errln(cal.getMessage());
165         }
166     }
167 
168     /*
169      * 4916815: REGRESSION: Problem with java.util.Calendar VM 1.4.2-b28
170      */
171     public void Test4916815() {
172         logln("Set date to 2003/9/26 (Fri). Roll to Aug and back to Sep. "
173                 + "Set dayofweek to Sunday which should be 2003/9/21.");
174         Koyomi cal = new Koyomi();
175         cal.clear();
176         // 2003/9/26 (Fri)
177         cal.set(2003, SEPTEMBER, 26);
178         // Go to August then back to September
179         cal.roll(MONTH, -1);
180         cal.roll(MONTH, +1);
181         Koyomi cal2 = (Koyomi) cal.clone();
182         cal2.getTime();
183         // Sunday of the week should be 2003/9/21.
184         cal2.set(DAY_OF_WEEK, SUNDAY);
185         if (!cal2.checkDate(2003, SEPTEMBER, 21, SUNDAY)) {
186             errln(cal2.getMessage());
187         }
188     }
189 
190     /*
191      * 4867075: GregorianCalendar get() calls complete() internally, should getTime() too?
192      */
193     public void Test4867075() {
194         Koyomi cal = new Koyomi(Locale.US);
195         cal.clear();
196         cal.set(YEAR, 2004);
197         cal.set(WEEK_OF_YEAR, 1);
198         checkDate(cal, SUNDAY, 2003, DECEMBER, 28);
199         checkDate(cal, MONDAY, 2003, DECEMBER, 29);
200         checkDate(cal, TUESDAY, 2003, DECEMBER, 30);
201         checkDate(cal, WEDNESDAY, 2003, DECEMBER, 31);
202         checkDate(cal, THURSDAY, 2004, JANUARY, 1);
203         checkDate(cal, FRIDAY, 2004, JANUARY, 2);
204         checkDate(cal, SATURDAY, 2004, JANUARY, 3);
205     }
206 
207     private void checkDate(Koyomi cal, int dayOfWeek,
208             int expectedYear, int expectedMonth, int expectedDayOfMonth) {
209         cal.set(DAY_OF_WEEK, dayOfWeek);
210         cal.getTime();
211         if (!cal.checkInternalDate(expectedYear, expectedMonth, expectedDayOfMonth, dayOfWeek)) {
212             errln(cal.getMessage());
213         }
214     }
215 
216     static String toHexString(int x) {
217         return Integer.toHexString(x);
218     }
219 }