PR libgcj/2641, PR libgcj/9854, PR libgcj/14892, PR libgcj/18083,
authorSven de Marothy <sven@physto.se>
Wed, 23 Mar 2005 21:26:00 +0000 (22:26 +0100)
committerTom Tromey <tromey@gcc.gnu.org>
Wed, 23 Mar 2005 21:26:00 +0000 (21:26 +0000)
2005-03-23  Sven de Marothy  <sven@physto.se>

PR libgcj/2641, PR libgcj/9854, PR libgcj/14892, PR libgcj/18083,
PR libgcj/11085:
* java/util/Calendar.java
(set): Use starting day of week when one is needed if none is given.
* java/text/SimpleDateFormat.java
(parse): Handle 1-12 and 1-24 timestamps correctly.
* java/util/GregorianCalendar.java
(computeTime, computeFields): HOUR should be in 0-11 format.
(nonLeniencyCheck): Adjust leniency checking to that fact.
(getLinearDay): Should be private.

From-SVN: r96951

libjava/ChangeLog
libjava/java/text/SimpleDateFormat.java
libjava/java/util/Calendar.java
libjava/java/util/GregorianCalendar.java

index 14c5079f3f91cb7131a550a7cbe0cead44b7fcf2..dc311113164d4d7e061565c0e68a2ab6b56a314c 100644 (file)
@@ -1,3 +1,16 @@
+2005-03-23  Sven de Marothy  <sven@physto.se>
+
+       PR libgcj/2641, PR libgcj/9854, PR libgcj/14892, PR libgcj/18083,
+       PR libgcj/11085:
+       * java/util/Calendar.java
+       (set): Use starting day of week when one is needed if none is given.
+       * java/text/SimpleDateFormat.java
+       (parse): Handle 1-12 and 1-24 timestamps correctly.
+       * java/util/GregorianCalendar.java
+       (computeTime, computeFields): HOUR should be in 0-11 format.
+       (nonLeniencyCheck): Adjust leniency checking to that fact.
+       (getLinearDay): Should be private.
+
 2005-03-23  Tom Tromey  <tromey@redhat.com>
  
        * include/jvm.h (GCJ_40_BC_ABI_VERSION): New define.
index c1eb3cd3a7078c944f5023a70eb77e7027e4101c..190b4d624f4759efd537dd1254a731463001a633 100644 (file)
@@ -916,6 +916,8 @@ public class SimpleDateFormat extends DateFormat
            boolean is_numeric = true;
            int offset = 0;
            boolean maybe2DigitYear = false;
+           boolean oneBasedHour = false;
+           boolean oneBasedHourOfDay = false;
            Integer simpleOffset;
            String[] set1 = null;
            String[] set2 = null;
@@ -964,12 +966,14 @@ public class SimpleDateFormat extends DateFormat
                break;
              case 'h':
                calendar_field = Calendar.HOUR;
+               oneBasedHour = true;
                break;
              case 'H':
                calendar_field = Calendar.HOUR_OF_DAY;
                break;
              case 'k':
                calendar_field = Calendar.HOUR_OF_DAY;
+               oneBasedHourOfDay = true;
                break;
              case 'm':
                calendar_field = Calendar.MINUTE;
@@ -1108,6 +1112,14 @@ public class SimpleDateFormat extends DateFormat
                  }
              }
            
+           // Calendar uses 0-based hours. 
+           // I.e. 00:00 AM is midnight, not 12 AM or 24:00
+           if (oneBasedHour && value == 12)
+             value = 0;
+
+           if (oneBasedHourOfDay && value == 24)
+             value = 0;
+           
            // Assign the value and move on.
            calendar.set(calendar_field, value);
          }
index 0e9284c7c212479e8fe8fe26b616d55a39f1ead6..7faaeee43bc8235649c93a9314e7f06b13f3c835 100644 (file)
@@ -706,6 +706,8 @@ public abstract class Calendar implements Serializable, Cloneable
        isSet[WEEK_OF_YEAR] = false;
        break;
       case WEEK_OF_MONTH: // pattern 2
+       if (! isSet[DAY_OF_WEEK])
+         fields[DAY_OF_WEEK] = getFirstDayOfWeek();
        isSet[YEAR] = true;
        isSet[MONTH] = true;
        isSet[DAY_OF_WEEK] = true;
@@ -715,6 +717,8 @@ public abstract class Calendar implements Serializable, Cloneable
        isSet[WEEK_OF_YEAR] = false;
        break;
       case DAY_OF_WEEK_IN_MONTH: // pattern 3
+       if (! isSet[DAY_OF_WEEK])
+         fields[DAY_OF_WEEK] = getFirstDayOfWeek();
        isSet[YEAR] = true;
        isSet[MONTH] = true;
        isSet[DAY_OF_WEEK] = true;
@@ -733,6 +737,8 @@ public abstract class Calendar implements Serializable, Cloneable
        isSet[DAY_OF_WEEK_IN_MONTH] = false;
        break;
       case WEEK_OF_YEAR: // pattern 5
+       if (! isSet[DAY_OF_WEEK])
+         fields[DAY_OF_WEEK] = getFirstDayOfWeek();
        isSet[YEAR] = true;
        isSet[DAY_OF_WEEK] = true;
        isSet[MONTH] = false;
index 710dd56f58bd0d51afa0b0130f5111659ad77e04..d036cd620e8c92444b3dbbe1e640a61e7ecdd8e9 100644 (file)
@@ -275,7 +275,6 @@ public class GregorianCalendar extends Calendar
    * Constructs a new GregorianCalendar representing midnight on the
    * given date with the default time zone and locale.
    *
-   *
    * @param year corresponds to the YEAR time field.
    * @param month corresponds to the MONTH time field.
    * @param day corresponds to the DAY time field.
@@ -478,7 +477,7 @@ public class GregorianCalendar extends Calendar
 
     if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM)
       throw new IllegalArgumentException("Illegal AM_PM.");
-    if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 12))
+    if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 11))
       throw new IllegalArgumentException("Illegal HOUR.");
     if (isSet[HOUR_OF_DAY]
         && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23))
@@ -564,10 +563,18 @@ public class GregorianCalendar extends Calendar
            // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
            if (isSet[DAY_OF_WEEK_IN_MONTH])
              {
+               if (fields[DAY_OF_WEEK_IN_MONTH] < 0)
+                 {
+                   month++;
+                   first = getFirstDayOfMonth(year, month);
+                   day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH]);
+                 }
+               else
+                 day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1);
+
                int offs = fields[DAY_OF_WEEK] - first;
                if (offs < 0)
                  offs += 7;
-               day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1);
                day += offs;
              }
            else
@@ -584,7 +591,7 @@ public class GregorianCalendar extends Calendar
 
                day = offs + 7 * (fields[WEEK_OF_MONTH] - 1);
                offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek();
-               if (offs < 0)
+               if (offs <= 0)
                  offs += 7;
                day += offs;
              }
@@ -602,11 +609,7 @@ public class GregorianCalendar extends Calendar
       {
        hour = fields[HOUR];
        if (fields[AM_PM] == PM)
-         if (hour != 12) /* not Noon */
-           hour += 12;
-       /* Fix the problem of the status of 12:00 AM (midnight). */
-       if (fields[AM_PM] == AM && hour == 12)
-         hour = 0;
+         hour += 12;
       }
     else
       hour = fields[HOUR_OF_DAY];
@@ -709,15 +712,15 @@ public class GregorianCalendar extends Calendar
    * @param gregorian <code>true</code>, if we should use the Gregorian rules.
    * @return the days since the epoch, may be negative.
    */
-   public long getLinearDay(int year, int dayOfYear, boolean gregorian)
-    {
-     // The 13 is the number of days, that were omitted in the Gregorian
-     // Calender until the epoch.
-     // We shift right by 2 instead of dividing by 4, to get correct
-     // results for negative years (and this is even more efficient).
-     long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1)
-                      - EPOCH_DAYS; // gregorian days from 1 to epoch.
+  private long getLinearDay(int year, int dayOfYear, boolean gregorian)
+  {
+    // The 13 is the number of days, that were omitted in the Gregorian
+    // Calender until the epoch.
+    // We shift right by 2 instead of dividing by 4, to get correct
+    // results for negative years (and this is even more efficient).
+    long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1)
+                     - EPOCH_DAYS; // gregorian days from 1 to epoch.
+
     if (gregorian)
       {
        // subtract the days that are missing in gregorian calendar
@@ -858,7 +861,7 @@ public class GregorianCalendar extends Calendar
     int hourOfDay = millisInDay / (60 * 60 * 1000);
     fields[AM_PM] = (hourOfDay < 12) ? AM : PM;
     int hour = hourOfDay % 12;
-    fields[HOUR] = (hour == 0) ? 12 : hour;
+    fields[HOUR] = hour;
     fields[HOUR_OF_DAY] = hourOfDay;
     millisInDay %= (60 * 60 * 1000);
     fields[MINUTE] = millisInDay / (60 * 1000);
@@ -925,9 +928,7 @@ public class GregorianCalendar extends Calendar
          }
        int maxDay = getActualMaximum(DAY_OF_MONTH);
        if (fields[DAY_OF_MONTH] > maxDay)
-         {
-           fields[DAY_OF_MONTH] = maxDay;
-         }
+         fields[DAY_OF_MONTH] = maxDay;
        set(YEAR, fields[YEAR]);
        set(MONTH, fields[MONTH]);
        break;