PR libgcj/2641, PR libgcj/9854, PR libgcj/14892, PR libgcj/18083,

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
This commit is contained in:
Sven de Marothy 2005-03-23 22:26:00 +01:00 committed by Tom Tromey
parent 85c4f26a86
commit 8d3ece5d90
4 changed files with 54 additions and 22 deletions

View 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> 2005-03-23 Tom Tromey <tromey@redhat.com>
* include/jvm.h (GCJ_40_BC_ABI_VERSION): New define. * include/jvm.h (GCJ_40_BC_ABI_VERSION): New define.

View File

@ -916,6 +916,8 @@ public class SimpleDateFormat extends DateFormat
boolean is_numeric = true; boolean is_numeric = true;
int offset = 0; int offset = 0;
boolean maybe2DigitYear = false; boolean maybe2DigitYear = false;
boolean oneBasedHour = false;
boolean oneBasedHourOfDay = false;
Integer simpleOffset; Integer simpleOffset;
String[] set1 = null; String[] set1 = null;
String[] set2 = null; String[] set2 = null;
@ -964,12 +966,14 @@ public class SimpleDateFormat extends DateFormat
break; break;
case 'h': case 'h':
calendar_field = Calendar.HOUR; calendar_field = Calendar.HOUR;
oneBasedHour = true;
break; break;
case 'H': case 'H':
calendar_field = Calendar.HOUR_OF_DAY; calendar_field = Calendar.HOUR_OF_DAY;
break; break;
case 'k': case 'k':
calendar_field = Calendar.HOUR_OF_DAY; calendar_field = Calendar.HOUR_OF_DAY;
oneBasedHourOfDay = true;
break; break;
case 'm': case 'm':
calendar_field = Calendar.MINUTE; 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. // Assign the value and move on.
calendar.set(calendar_field, value); calendar.set(calendar_field, value);
} }

View File

@ -706,6 +706,8 @@ public abstract class Calendar implements Serializable, Cloneable
isSet[WEEK_OF_YEAR] = false; isSet[WEEK_OF_YEAR] = false;
break; break;
case WEEK_OF_MONTH: // pattern 2 case WEEK_OF_MONTH: // pattern 2
if (! isSet[DAY_OF_WEEK])
fields[DAY_OF_WEEK] = getFirstDayOfWeek();
isSet[YEAR] = true; isSet[YEAR] = true;
isSet[MONTH] = true; isSet[MONTH] = true;
isSet[DAY_OF_WEEK] = true; isSet[DAY_OF_WEEK] = true;
@ -715,6 +717,8 @@ public abstract class Calendar implements Serializable, Cloneable
isSet[WEEK_OF_YEAR] = false; isSet[WEEK_OF_YEAR] = false;
break; break;
case DAY_OF_WEEK_IN_MONTH: // pattern 3 case DAY_OF_WEEK_IN_MONTH: // pattern 3
if (! isSet[DAY_OF_WEEK])
fields[DAY_OF_WEEK] = getFirstDayOfWeek();
isSet[YEAR] = true; isSet[YEAR] = true;
isSet[MONTH] = true; isSet[MONTH] = true;
isSet[DAY_OF_WEEK] = true; isSet[DAY_OF_WEEK] = true;
@ -733,6 +737,8 @@ public abstract class Calendar implements Serializable, Cloneable
isSet[DAY_OF_WEEK_IN_MONTH] = false; isSet[DAY_OF_WEEK_IN_MONTH] = false;
break; break;
case WEEK_OF_YEAR: // pattern 5 case WEEK_OF_YEAR: // pattern 5
if (! isSet[DAY_OF_WEEK])
fields[DAY_OF_WEEK] = getFirstDayOfWeek();
isSet[YEAR] = true; isSet[YEAR] = true;
isSet[DAY_OF_WEEK] = true; isSet[DAY_OF_WEEK] = true;
isSet[MONTH] = false; isSet[MONTH] = false;

View File

@ -275,7 +275,6 @@ public class GregorianCalendar extends Calendar
* Constructs a new GregorianCalendar representing midnight on the * Constructs a new GregorianCalendar representing midnight on the
* given date with the default time zone and locale. * given date with the default time zone and locale.
* *
*
* @param year corresponds to the YEAR time field. * @param year corresponds to the YEAR time field.
* @param month corresponds to the MONTH time field. * @param month corresponds to the MONTH time field.
* @param day corresponds to the DAY 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) if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM)
throw new IllegalArgumentException("Illegal AM_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."); throw new IllegalArgumentException("Illegal HOUR.");
if (isSet[HOUR_OF_DAY] if (isSet[HOUR_OF_DAY]
&& (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23)) && (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 // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
if (isSet[DAY_OF_WEEK_IN_MONTH]) 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; int offs = fields[DAY_OF_WEEK] - first;
if (offs < 0) if (offs < 0)
offs += 7; offs += 7;
day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1);
day += offs; day += offs;
} }
else else
@ -584,7 +591,7 @@ public class GregorianCalendar extends Calendar
day = offs + 7 * (fields[WEEK_OF_MONTH] - 1); day = offs + 7 * (fields[WEEK_OF_MONTH] - 1);
offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek();
if (offs < 0) if (offs <= 0)
offs += 7; offs += 7;
day += offs; day += offs;
} }
@ -602,11 +609,7 @@ public class GregorianCalendar extends Calendar
{ {
hour = fields[HOUR]; hour = fields[HOUR];
if (fields[AM_PM] == PM) if (fields[AM_PM] == PM)
if (hour != 12) /* not Noon */ hour += 12;
hour += 12;
/* Fix the problem of the status of 12:00 AM (midnight). */
if (fields[AM_PM] == AM && hour == 12)
hour = 0;
} }
else else
hour = fields[HOUR_OF_DAY]; 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. * @param gregorian <code>true</code>, if we should use the Gregorian rules.
* @return the days since the epoch, may be negative. * @return the days since the epoch, may be negative.
*/ */
public long getLinearDay(int year, int dayOfYear, boolean gregorian) private long getLinearDay(int year, int dayOfYear, boolean gregorian)
{ {
// The 13 is the number of days, that were omitted in the Gregorian // The 13 is the number of days, that were omitted in the Gregorian
// Calender until the epoch. // Calender until the epoch.
// We shift right by 2 instead of dividing by 4, to get correct // We shift right by 2 instead of dividing by 4, to get correct
// results for negative years (and this is even more efficient). // results for negative years (and this is even more efficient).
long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1) long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1)
- EPOCH_DAYS; // gregorian days from 1 to epoch. - EPOCH_DAYS; // gregorian days from 1 to epoch.
if (gregorian) if (gregorian)
{ {
// subtract the days that are missing in gregorian calendar // subtract the days that are missing in gregorian calendar
@ -858,7 +861,7 @@ public class GregorianCalendar extends Calendar
int hourOfDay = millisInDay / (60 * 60 * 1000); int hourOfDay = millisInDay / (60 * 60 * 1000);
fields[AM_PM] = (hourOfDay < 12) ? AM : PM; fields[AM_PM] = (hourOfDay < 12) ? AM : PM;
int hour = hourOfDay % 12; int hour = hourOfDay % 12;
fields[HOUR] = (hour == 0) ? 12 : hour; fields[HOUR] = hour;
fields[HOUR_OF_DAY] = hourOfDay; fields[HOUR_OF_DAY] = hourOfDay;
millisInDay %= (60 * 60 * 1000); millisInDay %= (60 * 60 * 1000);
fields[MINUTE] = millisInDay / (60 * 1000); fields[MINUTE] = millisInDay / (60 * 1000);
@ -925,9 +928,7 @@ public class GregorianCalendar extends Calendar
} }
int maxDay = getActualMaximum(DAY_OF_MONTH); int maxDay = getActualMaximum(DAY_OF_MONTH);
if (fields[DAY_OF_MONTH] > maxDay) if (fields[DAY_OF_MONTH] > maxDay)
{ fields[DAY_OF_MONTH] = maxDay;
fields[DAY_OF_MONTH] = maxDay;
}
set(YEAR, fields[YEAR]); set(YEAR, fields[YEAR]);
set(MONTH, fields[MONTH]); set(MONTH, fields[MONTH]);
break; break;