Patch: java.util.Calendar

Jeff Sturm jsturm@one-point.com
Wed Apr 25 13:38:00 GMT 2001


Calendar.add() in libgcj doesn't behave as the JDK does.  This patch
brings it closer.  It still not be 100% correct, but I'd like to see this
working in 3.0 if possible.

I have an incomplete Calendar test that passes libgcj with the patch
below.  When I get a little more time I'll figure out how to get the tests
into Mauve, which doesn't test Calendar yet.

With this and Warren's fixes to SimpleDateFormat, the Jacl test suite now
runs to completion.

2001-04-25  Jeff Sturm  <jsturm@one-point.com>

	* Calendar.java (get): Clear areFieldsSet if requested field
	is not set.
	(set): Unset fields that depend on new value.
	* GregorianCalendar.java (add): Use get, set to alter field.
	(adjust): Ditto.

Index: Calendar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/util/Calendar.java,v
retrieving revision 1.8
diff -u -p -r1.8 Calendar.java
--- Calendar.java	2000/12/28 05:55:56	1.8
+++ Calendar.java	2001/04/25 16:21:08
@@ -522,6 +522,9 @@ public abstract class Calendar implement
    */
   public final int get(int field)
   {
+    // If the requested field is invalid, force all fields to be recomputed.
+    if (!isSet[field])
+      areFieldsSet = false;
     complete();
     return fields[field];
   }
@@ -551,6 +554,29 @@ public abstract class Calendar implement
     isTimeSet = false;
     fields[field] = value;
     isSet[field] = true;
+    switch (field)
+      {
+      case YEAR:
+      case MONTH:
+      case DATE:
+	isSet[WEEK_OF_YEAR] = false;
+	isSet[DAY_OF_YEAR] = false;
+	isSet[WEEK_OF_MONTH] = false;
+	isSet[DAY_OF_WEEK] = false;
+	isSet[DAY_OF_WEEK_IN_MONTH] = false;
+	break;
+      case AM_PM:
+	isSet[HOUR_OF_DAY] = false;
+	break;
+      case HOUR_OF_DAY:
+	isSet[AM_PM] = false;
+	isSet[HOUR] = false;
+	break;
+      case HOUR:
+	isSet[AM_PM] = false;
+	isSet[HOUR_OF_DAY] = false;
+	break;
+      }
   }
 
   /**
@@ -568,6 +594,11 @@ public abstract class Calendar implement
     fields[MONTH] = month;
     fields[DATE] = date;
     isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true;
+    isSet[WEEK_OF_YEAR] = false;
+    isSet[DAY_OF_YEAR] = false;
+    isSet[WEEK_OF_MONTH] = false;
+    isSet[DAY_OF_WEEK] = false;
+    isSet[DAY_OF_WEEK_IN_MONTH] = false;
   }
 
   /**
@@ -584,6 +615,8 @@ public abstract class Calendar implement
     fields[HOUR_OF_DAY] = hour;
     fields[MINUTE] = minute;
     isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
+    isSet[AM_PM] = false;
+    isSet[HOUR] = false;
   }
 
   /**
Index: GregorianCalendar.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/util/GregorianCalendar.java,v
retrieving revision 1.8
diff -u -p -r1.8 GregorianCalendar.java
--- GregorianCalendar.java	2000/12/28 05:55:56	1.8
+++ GregorianCalendar.java	2001/04/25 16:21:09
@@ -150,8 +150,8 @@ public class GregorianCalendar extends C
   {
     if (fld >= ZONE_OFFSET)
       throw new IllegalArgumentException("bad field to add");
-    fields[fld] += amount;
-    adjust(fld);
+    set (fld, get (fld) + amount);
+    adjust (fld);
   }
 
   public void roll (int fld, boolean up)
@@ -174,26 +174,32 @@ public class GregorianCalendar extends C
 
   private void adjust (int fld)
   {
-    int value = fields[fld];
+    int value = get (fld);
     int radix = maxs[fld] + 1;
     switch (fld)
       {
       case MONTH:
+      case DATE:
+      case HOUR_OF_DAY:
+      case MINUTE:
       case SECOND:
       case MILLISECOND:
 	if (value >= radix)
 	  {
 	    int next = value / radix;
-	    fields[fld] = value - radix * next;
-	    fields[fld - 1] += next;
-	    adjust(fld - 1);
+	    set (fld, value - radix * next);
+	    if (next > 0)
+	      {
+		set (fld - 1, get (fld - 1) + next);
+		adjust (fld - 1);
+	      }
 	  }
 	else if (value < 0) // min[fld]
 	  {
 	    int next = (value - radix - 1) / radix;
-	    fields[fld] = value - radix * next;
-	    fields[fld - 1] += next;
-            adjust(fld - 1);
+	    set (fld, value - radix * next);
+	    set (fld - 1, get (fld - 1) + next);
+            adjust (fld - 1);
 	  }
 	break;
       }



More information about the Java-patches mailing list