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 
  31 import java.util.*;
  32 import static java.util.GregorianCalendar.*;
  33 
  34 // Usage: java DateGregorianCalendarTest [duration]
  35 
  36 @SuppressWarnings("deprecation")
  37 public 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 }