GregorianCalendar.java (computeTime): Skip buggy formulae when we already know the...
authorJerry Quinn <jlquinn@optonline.net>
Fri, 11 Jun 2004 05:54:02 +0000 (05:54 +0000)
committerJerry Quinn <jlquinn@gcc.gnu.org>
Fri, 11 Jun 2004 05:54:02 +0000 (05:54 +0000)
2004-06-11  Jerry Quinn  <jlquinn@optonline.net>

* java/util/GregorianCalendar.java (computeTime):  Skip buggy formulae
when we already know the answer.
* java/util/SimpleTimeZone.java (serialVersionOnStream): Bump to 2.
(setStartRule,setEndRule): Don't take abs of day number.
(getOffset): Clarify docs.  Add argument checks.
(isBefore): Take abs of day number in DOW_LE_DOM_MODE.
(equals,hasSameRules,toString,readObject): Use startTimeMode and
endTimeMode.

From-SVN: r82962

libjava/ChangeLog
libjava/java/util/GregorianCalendar.java
libjava/java/util/SimpleTimeZone.java

index 35c659b852d3c65236e017f61091f56c5af140be..5b1c89ee91c0f109579939eca9bc8a522dde9453 100644 (file)
@@ -1,3 +1,14 @@
+2004-06-11  Jerry Quinn  <jlquinn@optonline.net>
+
+       * java/util/GregorianCalendar.java (computeTime):  Skip buggy formulae
+       when we already know the answer.
+       * java/util/SimpleTimeZone.java (serialVersionOnStream): Bump to 2.
+       (setStartRule,setEndRule): Don't take abs of day number.
+       (getOffset): Clarify docs.  Add argument checks.
+       (isBefore): Take abs of day number in DOW_LE_DOM_MODE.
+       (equals,hasSameRules,toString,readObject): Use startTimeMode and
+       endTimeMode.
+
 2004-06-10  Tom Tromey  <tromey@redhat.com>
 
        * interpret.cc (run): Handle wide fload.
index 1d3d2f0ab0e4b86485cd4a8d48f58a8e07bbdddf..8f644cba0414af2eaaa0256d4614e90cc4cb8d3e 100644 (file)
@@ -1,5 +1,6 @@
 /* java.util.GregorianCalendar
-   Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -441,8 +442,15 @@ public class GregorianCalendar extends Calendar
       ? fields[ZONE_OFFSET] : zone.getRawOffset();
 
     int dayOfYear = daysOfYear[0] + daysOfYear[1];
-    int month = (dayOfYear * 5 + 3) / (31 + 30 + 31 + 30 + 31);
-    int day = (6 + (dayOfYear * 5 + 3) % (31 + 30 + 31 + 30 + 31)) / 5;
+    // This formula isn't right, so check for month as a quick fix.
+    // It doesn't compensate for leap years and puts day 30 in month 1
+    // instead of month 0.
+    int month = isSet[MONTH]
+       ? fields[MONTH] : (dayOfYear * 5 + 3) / (31 + 30 + 31 + 30 + 31);
+    // This formula isn't right, so check for day as a quick fix.  It
+    // doesn't compensate for leap years, either.
+    int day = isSet[DAY_OF_MONTH] ? fields[DAY_OF_MONTH]
+       : (6 + (dayOfYear * 5 + 3) % (31 + 30 + 31 + 30 + 31)) / 5;
     int weekday = ((int) (time / (24 * 60 * 60 * 1000L)) + THURSDAY) % 7;
     if (weekday <= 0)
       weekday += 7;
index 71f92e88f34a81b80d0370723d441ef85175f936..648b6753267d7cfc41e47a41b57afc6fd713e30b 100644 (file)
@@ -234,7 +234,7 @@ public class SimpleTimeZone extends TimeZone
    * @serial
    * @since JDK1.1.4 
    */
-  private int serialVersionOnStream = 1;
+  private int serialVersionOnStream = 2;
 
   private static final long serialVersionUID = -403250971215465050L;
 
@@ -477,9 +477,7 @@ public class SimpleTimeZone extends TimeZone
   {
     this.startMode = checkRule(month, day, dayOfWeek);
     this.startMonth = month;
-    // FIXME: XXX: JDK 1.2 allows negative values and has 2 new variations
-    // of this method.
-    this.startDay = Math.abs(day);
+    this.startDay = day;
     this.startDayOfWeek = Math.abs(dayOfWeek);
     if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME)
       this.startTime = time;
@@ -570,9 +568,7 @@ public class SimpleTimeZone extends TimeZone
   {
     this.endMode = checkRule(month, day, dayOfWeek);
     this.endMonth = month;
-    // FIXME: XXX: JDK 1.2 allows negative values and has 2 new variations
-    // of this method.
-    this.endDay = Math.abs(day);
+    this.endDay = day;
     this.endDayOfWeek = Math.abs(dayOfWeek);
     if (this.endTimeMode == WALL_TIME)
       this.endTime = time;
@@ -660,21 +656,33 @@ public class SimpleTimeZone extends TimeZone
    * <code>offset = cal.get(Calendar.ZONE_OFFSET)
    * + cal.get(Calendar.DST_OFFSET);</code>
    *
-   * You could also use in
-   *
    * This version doesn't suffer this inaccuracy.
    *
+   * The arguments don't follow the approach for setting start and end rules.
+   * The day must be a positive number and dayOfWeek must be a positive value
+   * from Calendar.  dayOfWeek is redundant, but must match the other values
+   * or an inaccurate result may be returned.
+   *
    * @param era the era of the given date
    * @param year the year of the given date
    * @param month the month of the given date, 0 for January.
    * @param day the day of month
-   * @param dayOfWeek the day of week; this must be matching the
-   * other fields.
+   * @param dayOfWeek the day of week; this must match the other fields.
    * @param millis the millis in the day (in local standard time)
-   * @return the time zone offset in milliseconds.  */
+   * @return the time zone offset in milliseconds.
+   * @throws IllegalArgumentException if arguments are incorrect.
+   */
   public int getOffset(int era, int year, int month,
                       int day, int dayOfWeek, int millis)
   {
+    int daysInMonth = getDaysInMonth(month, year);
+    if (day < 1 || day > daysInMonth)
+      throw new IllegalArgumentException("day out of range");
+    if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY)
+      throw new IllegalArgumentException("dayOfWeek out of range");
+    if (month < Calendar.JANUARY || month > Calendar.DECEMBER)
+      throw new IllegalArgumentException("month out of range");
+
     // This method is called by Calendar, so we mustn't use that class.
     int daylightSavings = 0;
     if (useDaylight && era == GregorianCalendar.AD && year >= startYear)
@@ -785,7 +793,7 @@ public class SimpleTimeZone extends TimeZone
   /**
    * Checks if the date given in calXXXX, is before the change between
    * dst and standard time.
-   * @param calYear the year of the date to check (for leap day cheking).
+   * @param calYear the year of the date to check (for leap day checking).
    * @param calMonth the month of the date to check.
    * @param calDay the day of month of the date to check.
    * @param calDayOfWeek the day of week of the date to check.
@@ -870,7 +878,7 @@ public class SimpleTimeZone extends TimeZone
       case DOW_LE_DOM_MODE:
        // The greatest sunday before or equal December, 12
        // is the same as smallest sunday after or equal December, 6.
-       day -= 6;
+       day = Math.abs(day) - 6;
 
       case DOW_GE_DOM_MODE:
 
@@ -931,10 +939,12 @@ public class SimpleTimeZone extends TimeZone
            && startDay == zone.startDay
            && startDayOfWeek == zone.startDayOfWeek
            && startTime == zone.startTime
+           && startTimeMode == zone.startTimeMode
            && endMonth == zone.endMonth
            && endDay == zone.endDay
            && endDayOfWeek == zone.endDayOfWeek
-           && endTime == zone.endTime);
+           && endTime == zone.endTime
+           && endTimeMode == zone.endTimeMode);
   }
 
   /**
@@ -962,9 +972,12 @@ public class SimpleTimeZone extends TimeZone
            && startDay == zone.startDay
            && startDayOfWeek == zone.startDayOfWeek
            && startTime == zone.startTime
+           && startTimeMode == zone.startTimeMode
            && endMonth == zone.endMonth
            && endDay == zone.endDay
-           && endDayOfWeek == zone.endDayOfWeek && endTime == zone.endTime);
+           && endDayOfWeek == zone.endDayOfWeek
+           && endTime == zone.endTime
+           && endTimeMode == zone.endTimeMode);
   }
 
   /**
@@ -987,11 +1000,14 @@ public class SimpleTimeZone extends TimeZone
         + ",startDay=" + startDay
         + ",startDayOfWeek=" + startDayOfWeek
         + ",startTime=" + startTime
+        + ",startTimeMode=" + startTimeMode
         + ",endMode=" + endMode
         + ",endMonth=" + endMonth
         + ",endDay=" + endDay
         + ",endDayOfWeek=" + endDayOfWeek
-        + ",endTime=" + endTime : "") + "]";
+        + ",endTime=" + endTime
+        + ",endTimeMode=" + endTimeMode
+        : "") + "]";
   }
 
   /**
@@ -1008,8 +1024,9 @@ public class SimpleTimeZone extends TimeZone
        dstSavings = 60 * 60 * 1000;
        endMode = DOW_IN_MONTH_MODE;
        startMode = DOW_IN_MONTH_MODE;
-       serialVersionOnStream = 1;
-      }
+       startTimeMode = WALL_TIME;
+       endTimeMode = WALL_TIME;
+       serialVersionOnStream = 2;      }
     else
       {
        int length = input.readInt();