1 /*
  2  * Copyright (c) 1997, 2023, 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 4143459
 27  * @summary test Date
 28  * @run junit DateTest
 29  */
 30 
 31 import java.text.*;
 32 import java.util.*;
 33 
 34 import org.junit.jupiter.api.Test;
 35 
 36 import static org.junit.jupiter.api.Assertions.fail;
 37 
 38 @SuppressWarnings("deprecation")
 39 public class DateTest
 40 {
 41     /**
 42      * @bug 4143459
 43      * Warning: Use TestDefaultZone() for complete testing of this bug.
 44      */
 45     @Test
 46     public void TestDefaultZoneLite() {
 47         // Note: This test is redundant with TestDefaultZone().  It was added by
 48         // request to provide a short&sweet test for this bug.  It does not test
 49         // all cases though, so IF THIS TEST PASSES, THE BUG MAY STILL BE
 50         // PRESENT.  Use TestDefaultZone() to be sure.
 51         TimeZone save = TimeZone.getDefault();
 52         try {
 53             TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
 54             Date d = new Date();
 55             d.setYear(98);
 56             d.setMonth(Calendar.JANUARY);
 57             d.setDate(1);
 58             d.setHours(6);
 59             TimeZone.setDefault(TimeZone.getTimeZone("PST"));
 60             if (d.getHours() != 22) {
 61                 fail("Fail: Date.setHours()/getHours() ignoring default zone");
 62             }
 63         }
 64         finally { TimeZone.setDefault(save); }
 65     }
 66 
 67     /**
 68      * @bug 4143459
 69      */
 70     @Test
 71     public void TestDefaultZone() {
 72         // Various problems can creep up, with the current implementation of Date,
 73         // when the default zone is changed.
 74 
 75         TimeZone saveZone = TimeZone.getDefault();
 76         try {
 77 
 78             Date d = new Date(); // Trigger static init
 79             Date ref = new Date(883634400000L); // This is Thu Jan 1 1998 6:00 am GMT
 80             String refstr = "Jan 1 1998 6:00";
 81             TimeZone GMT = TimeZone.getTimeZone("GMT");
 82             TimeZone PST = TimeZone.getTimeZone("PST");
 83 
 84             String[] names = { "year", "month", "date", "day of week", "hour", "offset" };
 85             int[] GMT_EXP = { 98, Calendar.JANUARY, 1, Calendar.THURSDAY - Calendar.SUNDAY, 6, 0 };
 86             int[] PST_EXP = { 97, Calendar.DECEMBER, 31, Calendar.WEDNESDAY - Calendar.SUNDAY, 22, 480 };
 87 
 88             // There are two cases to consider: a Date object with no Calendar
 89             // sub-object (most Date objects), and a Date object with a Calendar
 90             // sub-object.  We make two passes to cover the two cases.
 91             for (int pass=0; pass<2; ++pass) {
 92                 System.out.println(pass == 0 ? "Normal Date object" : "Date with Calendar sub-object");
 93 
 94                 TimeZone.setDefault(GMT);
 95                 d = new Date(refstr);
 96                 if (pass == 1) {
 97                     // Force creation of Calendar sub-object
 98                     d.setYear(d.getYear());
 99                 }
100                 if (d.getTime() != ref.getTime()) {
101                     fail("FAIL: new Date(\"" + refstr + "\") x GMT -> " + d +
102                           " " + d.getTime() + " ms");
103                 }
104 
105                 int[] fields = { d.getYear(), d.getMonth(), d.getDate(),
106                                  d.getDay(), d.getHours(), d.getTimezoneOffset() };
107                 for (int i=0; i<fields.length; ++i) {
108                     if (fields[i] != GMT_EXP[i]) {
109                         fail("FAIL: GMT Expected " + names[i] + " of " + GMT_EXP[i] +
110                               ", got " + fields[i]);
111                     }
112                 }
113 
114                 TimeZone.setDefault(PST);
115                 int[] fields2 = { d.getYear(), d.getMonth(), d.getDate(),
116                                   d.getDay(), d.getHours(), d.getTimezoneOffset() };
117                 for (int i=0; i<fields2.length; ++i) {
118                     if (fields2[i] != PST_EXP[i]) {
119                         fail("FAIL: PST Expected " + names[i] + " of " + PST_EXP[i] +
120                               ", got " + fields2[i]);
121                     }
122                 }
123             }
124         }
125         finally {
126             TimeZone.setDefault(saveZone);
127         }
128     }
129 
130     // Test the performance of Date
131     @Test
132     public void TestPerformance592()
133     {
134         int REPS = 500;
135 
136         // Do timing test with Date
137         long start = new Date().getTime();
138         for (int i=0; i<REPS; ++i)
139         {
140             Date d = new Date();
141             int y = d.getYear();
142         }
143         long ms = new Date().getTime() - start;
144 
145         double perLoop = ((double)ms) / REPS;
146         System.out.println(REPS + " iterations at " + perLoop + " ms/loop");
147         if (perLoop > PER_LOOP_LIMIT)
148             System.out.println("WARNING: Date constructor/getYear slower than " +
149                   PER_LOOP_LIMIT + " ms");
150     }
151     static double PER_LOOP_LIMIT = 3.0;
152 
153     /**
154      * Verify that the Date(String) constructor works.
155      */
156     @Test
157     public void TestParseOfGMT()
158     {
159         Date OUT = null;
160 
161         /* Input values */
162         String stringVal = "Jan 01 00:00:00 GMT 1900";
163         long expectedVal = -2208988800000L;
164 
165         OUT = new Date( stringVal );
166 
167         if( OUT.getTime( ) == expectedVal ) {
168             // logln("PASS");
169         }
170         else {
171             fail( "Expected: " +
172                    new Date( expectedVal ) +
173                    ": " +
174                    expectedVal +
175                    "  Received: " +
176                    OUT.toString() +
177                    ": " +
178                    OUT.getTime() );
179         }
180     }
181 
182     // Check out Date's behavior with large negative year values; bug 664
183     // As of the fix to bug 4056585, Date should work correctly with
184     // large negative years.
185     @Test
186     public void TestDateNegativeYears()
187     {
188         Date d1= new Date(80,-1,2);
189         System.out.println(d1.toString());
190         d1= new Date(-80,-1,2);
191         System.out.println(d1.toString());
192         boolean e = false;
193         try {
194             d1= new Date(-800000,-1,2);
195             System.out.println(d1.toString());
196         }
197         catch (IllegalArgumentException ex) {
198             e = true;
199         }
200         if (e) fail("FAIL: Saw exception for year -800000");
201         else System.out.println("Pass: No exception for year -800000");
202     }
203 
204     // Verify the behavior of Date
205     @Test
206     public void TestDate480()
207     {
208       TimeZone save = TimeZone.getDefault();
209       try {
210         TimeZone.setDefault(TimeZone.getTimeZone("PST"));
211         Date d1=new java.util.Date(97,8,13,10,8,13);
212         System.out.println("d       = "+d1);
213         Date d2=new java.util.Date(97,8,13,30,8,13); // 20 hours later
214         System.out.println("d+20h   = "+d2);
215 
216         double delta = (d2.getTime() - d1.getTime()) / 3600000;
217 
218         System.out.println("delta   = " + delta + "h");
219 
220         if (delta != 20.0) fail("Expected delta of 20; got " + delta);
221 
222         Calendar cal = Calendar.getInstance();
223         cal.clear();
224         cal.set(1997,8,13,10,8,13);
225         Date t1 = cal.getTime();
226         System.out.println("d       = "+t1);
227         cal.clear();
228         cal.set(1997,8,13,30,8,13); // 20 hours later
229         Date t2 = cal.getTime();
230         System.out.println("d+20h   = "+t2);
231 
232         double delta2 = (t2.getTime() - t1.getTime()) / 3600000;
233 
234         System.out.println("delta   = " + delta2 + "h");
235 
236         if (delta != 20.0) fail("Expected delta of 20; got " + delta2);
237       }
238       finally {
239         TimeZone.setDefault(save);
240       }
241     }
242 }