1/*
2 * Copyright (c) 2003, 2016, 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 4614842
27 * @summary Make sure that a Date and a GregorianCalendar produce the same date/time. Both are new implementations in 1.5.
28 * @run main DateGregorianCalendarTest 15
29 */
30
31import java.util.*;
32import static java.util.GregorianCalendar.*;
33
34// Usage: java DateGregorianCalendarTest [duration]
35
36@SuppressWarnings("deprecation")
37public class DateGregorianCalendarTest {
38    static volatile boolean runrun = true;
39    static int nThreads;
40
41    public static void main(String[] args) {
42        int duration = 600;
43        if (args.length == 1) {
44            duration = Math.max(10, Integer.parseInt(args[0]));
45        }
46
47        TimeZone savedTZ = TimeZone.getDefault();
48        try {
49            TimeZone.setDefault(TimeZone.getTimeZone("GMT"));
50            Thread[] t = new Thread[10]; // for future bugs...
51            int index = 0;
52            t[index++] = new Thread(new Runnable() {
53                    public void run() {
54                        GregorianCalendar gc = new GregorianCalendar();
55
56                        long delta = (long)(279 * 365.2422 * 24 * 60 * 60 * 1000);
57                        long count = 0;
58                        try {
59                            for (long t = Long.MIN_VALUE; runrun && t < Long.MAX_VALUE-delta; t += delta) {
60                                gc.setTimeInMillis(t);
61                                Date date = new Date(t);
62                                int y;
63                                if (!((y = gc.get(YEAR)) == (date.getYear()+1900) &&
64                                      gc.get(MONTH) == date.getMonth() &&
65                                      gc.get(DAY_OF_MONTH) == date.getDate() &&
66                                      gc.get(HOUR_OF_DAY) == date.getHours() &&
67                                      gc.get(MINUTE) == date.getMinutes() &&
68                                      gc.get(SECOND) == date.getSeconds())) {
69                                    throw new RuntimeException("GregorinCalendar and Date returned different dates."
70                                                               +" (millis=" + t + ")\n"
71                                                               +"GC=" + gc + "\nDate=" + date);
72                                }
73                                ++count;
74                                if (y >= 1) {
75                                    delta = (long)(365.2422 * 24 * 60 * 60 * 1000);
76                                }
77                                if (y >= 1970) {
78                                    delta = (24 * 60 * 60 * 1000);
79                                }
80                                if (y >= 2039) {
81                                    delta = (long)(279 * 365.2422 * 24 * 60 * 60 * 1000);
82                                }
83                            }
84                            if (runrun) {
85                                System.out.println("Part I (count="+count+"): Passed");
86                            } else {
87                                System.out.println("Part I (count="+count+"): Incomplete");
88                            }
89                        } catch (RuntimeException e) {
90                            System.out.println("Part I (count="+count+"): FAILED");
91                            runrun = false;
92                            throw e;
93                        } finally {
94                            decrementCounter();
95                        }
96                    }
97                });
98
99            t[index++] = new Thread(new Runnable() {
100                    public void run() {
101                        GregorianCalendar gc = new GregorianCalendar();
102
103                        long count = 0;
104                        int delta;
105                        try {
106                            for (long year = Integer.MIN_VALUE+1900;
107                                 runrun && year <= Integer.MAX_VALUE; year += delta) {
108                                checkTimes(gc, year, JANUARY, 1, 0, 0, 0);
109                                ++count;
110                                delta = getDelta((int)year);
111                            }
112
113                            for (long month = Integer.MIN_VALUE;
114                                 runrun && month <= Integer.MAX_VALUE; month += delta) {
115                                checkTimes(gc, 1900, month, 1, 0, 0, 0);
116                                ++count;
117                                delta = getDelta(gc.get(YEAR));
118                            }
119
120                            for (long dayOfMonth = Integer.MIN_VALUE;
121                                 runrun && dayOfMonth <= Integer.MAX_VALUE; dayOfMonth += delta) {
122                                checkTimes(gc, 1900, JANUARY, dayOfMonth, 0, 0, 0);
123                                ++count;
124                                delta = getDelta(gc.get(YEAR));
125                            }
126                            if (runrun) {
127                                System.out.println("Part II (count="+count+"): Passed");
128                            } else {
129                                System.out.println("Part II (count="+count+"): Incomplete");
130                            }
131                        } catch (RuntimeException e) {
132                            System.out.println("Part II (count="+count+"): FAILED");
133                            runrun = false;
134                            throw e;
135                        } finally {
136                            decrementCounter();
137                        }
138                    }
139                });
140
141            // t3 takes more than 10 minutes (on Ultra-60 450MHz) without
142            // the 4936355 fix due to getting the small delta.
143            t[index++] = new Thread(new Runnable() {
144                    public void run() {
145                        GregorianCalendar gc = new GregorianCalendar();
146
147                        long count = 0;
148                        int delta;
149                        try {
150                            for (long hourOfDay = Integer.MIN_VALUE;
151                                 runrun && hourOfDay <= Integer.MAX_VALUE; hourOfDay += delta) {
152                                checkTimes(gc, 1970, JANUARY, 1, hourOfDay, 0, 0);
153                                ++count;
154                                delta = getDelta(gc.get(YEAR));
155                            }
156                            for (long minutes = Integer.MIN_VALUE;
157                                 runrun && minutes <= Integer.MAX_VALUE; minutes += delta) {
158                                checkTimes(gc, 1970, JANUARY, 1, 0, minutes, 0);
159                                ++count;
160                                delta = getDelta(gc.get(YEAR)) * 60;
161                            }
162                            for (long seconds = Integer.MIN_VALUE;
163                                 runrun && seconds <= Integer.MAX_VALUE; seconds += delta) {
164                                checkTimes(gc, 1970, JANUARY, 1, 0, 0, seconds);
165                                ++count;
166                                delta = getDelta(gc.get(YEAR)) * 60 * 60;
167                            }
168                            if (runrun) {
169                                System.out.println("Part III (count="+count+"): Passed");
170                            } else {
171                                System.out.println("Part III (count="+count+"): Incomplete");
172                            }
173                        } catch (RuntimeException e) {
174                            System.out.println("Part III (count="+count+"): FAILED");
175                            runrun = false;
176                            throw e;
177                        } finally {
178                            decrementCounter();
179                        }
180                    }
181                });
182
183            for (int i = 0; i < index; i++) {
184                incrementCounter();
185                t[i].start();
186            }
187
188            try {
189                for (int i = 0; getCounter() > 0 && i < duration; i++) {
190                    Thread.sleep(1000);
191                }
192                runrun = false;
193                for (int i = 0; i < index; i++) {
194                    t[i].join();
195                }
196            } catch (InterruptedException e) {
197            }
198        } finally {
199            TimeZone.setDefault(savedTZ);
200        }
201    }
202
203    static void checkTimes(GregorianCalendar gc, long year, long month, long dayOfMonth,
204                           long hourOfDay, long minutes, long seconds) {
205        gc.clear();
206        gc.set((int)year, (int)month, (int)dayOfMonth, (int)hourOfDay, (int)minutes, (int)seconds);
207        long time = gc.getTimeInMillis();
208        Date date = new Date((int)year - 1900, (int)month, (int)dayOfMonth,
209                             (int)hourOfDay, (int)minutes, (int)seconds);
210        long time2 = date.getTime();
211        if (time != time2) {
212            throw new RuntimeException("GregorinCalendar and Date returned different values.\n"
213                                       +"year="+year+", month="+month+", dayOfMonth="+dayOfMonth
214                                       +"\nhourOfDay="+hourOfDay+", minutes="+minutes+", seconds="+seconds
215                                       +"\ntime=" + time + ", time2=" + time2
216                                       +"\nGC=" + gc + "\nDate=" + date);
217        }
218    }
219
220    static final int getDelta(int year) {
221        return (year >= 1970 && year <= 2039) ? 1 : 1<<13;
222    }
223
224    synchronized static void incrementCounter() {
225        nThreads++;
226    }
227
228    synchronized static void decrementCounter() {
229        nThreads--;
230    }
231
232    synchronized static int getCounter() {
233        return nThreads;
234    }
235}
236