[multiple changes]

2001-05-10  Tom Tromey  <tromey@redhat.com>

	* java/util/GregorianCalendar.java: Imported from Classpath.
	* gnu/java/locale/LocaleInformation_nl.java: New file from
	Classpath.
	* gnu/java/locale/LocaleInformation_en.java: Likewise.
	* gnu/java/locale/LocaleInformation_de.java: Likewise.
	* gnu/java/locale/LocaleInformation.java: Likewise.
	* natGregorianCalendar.cc: Removed.
	* Makefile.in: Rebuilt.
	* Makefile.am (nat_source_files): Removed
	natGregorianCalendar.cc.

2001-05-10  Tom Tromey  <tromey@redhat.com>

	* java/text/SimpleDateFormat.java (computeCenturyStart): New
	method.
	(defaultCenturyStart): Use it.
	(readObject): Likewise.
	(SimpleDateFormat): Clear the calendar.  Set the grouping on the
	number format.
	(parse): Copy the calendar before modifying it.  Correctly handle
	the time zone.

	* java/util/Calendar.java (clear): Set field value(s) to 0.

2001-05-10  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.

From-SVN: r41942
This commit is contained in:
Tom Tromey 2001-05-10 18:13:17 +00:00
parent b0089a92a3
commit 9622762678
11 changed files with 2101 additions and 415 deletions

View file

@ -62,8 +62,7 @@ public class SimpleDateFormat extends DateFormat
private transient Vector tokens;
private DateFormatSymbols formatData; // formatData
private Date defaultCenturyStart =
new Date(System.currentTimeMillis() - (80*365*24*60*60*1000));
private Date defaultCenturyStart = computeCenturyStart ();
private String pattern;
private int serialVersionOnStream = 1; // 0 indicates JDK1.1.3 or earlier
private static final long serialVersionUID = 4774881970558875024L;
@ -79,8 +78,7 @@ public class SimpleDateFormat extends DateFormat
stream.defaultReadObject();
if (serialVersionOnStream < 1)
{
defaultCenturyStart =
new Date(System.currentTimeMillis() - (80*365*24*60*60*1000));
defaultCenturyStart = computeCenturyStart ();
serialVersionOnStream = 1;
}
@ -161,11 +159,14 @@ public class SimpleDateFormat extends DateFormat
super();
Locale locale = Locale.getDefault();
calendar = new GregorianCalendar(locale);
calendar.clear ();
tokens = new Vector();
formatData = new DateFormatSymbols(locale);
pattern = formatData.dateFormats[DEFAULT]+' '+formatData.timeFormats[DEFAULT];
pattern = (formatData.dateFormats[DEFAULT] + ' '
+ formatData.timeFormats[DEFAULT]);
compileFormat(pattern);
numberFormat = NumberFormat.getInstance(locale);
numberFormat.setGroupingUsed (false);
}
/**
@ -185,20 +186,24 @@ public class SimpleDateFormat extends DateFormat
{
super();
calendar = new GregorianCalendar(locale);
calendar.clear ();
tokens = new Vector();
formatData = new DateFormatSymbols(locale);
compileFormat(pattern);
this.pattern = pattern;
numberFormat = NumberFormat.getInstance(locale);
numberFormat.setGroupingUsed (false);
}
/**
* Creates a date formatter using the specified pattern. The
* specified DateFormatSymbols will be used when formatting.
*/
public SimpleDateFormat(String pattern, DateFormatSymbols formatData) {
public SimpleDateFormat(String pattern, DateFormatSymbols formatData)
{
super();
calendar = new GregorianCalendar();
calendar.clear ();
// FIXME: XXX: Is it really necessary to set the timezone?
// The Calendar constructor is supposed to take care of this.
calendar.setTimeZone(TimeZone.getDefault());
@ -207,6 +212,7 @@ public class SimpleDateFormat extends DateFormat
compileFormat(pattern);
this.pattern = pattern;
numberFormat = NumberFormat.getInstance();
numberFormat.setGroupingUsed (false);
}
// What is the difference between localized and unlocalized? The
@ -377,7 +383,8 @@ public class SimpleDateFormat extends DateFormat
* appending to the specified StringBuffer. The input StringBuffer
* is returned as output for convenience.
*/
public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos) {
public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos)
{
String temp;
Calendar theCalendar = (Calendar) calendar.clone();
theCalendar.setTime(date);
@ -507,7 +514,10 @@ public class SimpleDateFormat extends DateFormat
int fmt_index = 0;
int fmt_max = pattern.length();
calendar.clear();
// We copy the Calendar because if we don't we will modify it and
// then this.equals() will no longer have the desired result.
Calendar theCalendar = (Calendar) calendar.clone ();
theCalendar.clear();
int quote_start = -1;
for (; fmt_index < fmt_max; ++fmt_index)
{
@ -553,7 +563,6 @@ public class SimpleDateFormat extends DateFormat
boolean is_numeric = true;
String[] match = null;
int offset = 0;
int zone_number = 0;
switch (ch)
{
case 'd':
@ -626,6 +635,7 @@ public class SimpleDateFormat extends DateFormat
// We need a special case for the timezone, because it
// uses a different data structure than the other cases.
is_numeric = false;
// We don't actually use this; see below.
calendar_field = Calendar.DST_OFFSET;
String[][] zoneStrings = formatData.getZoneStrings();
int zoneCount = zoneStrings.length;
@ -642,11 +652,11 @@ public class SimpleDateFormat extends DateFormat
}
if (k != strings.length)
{
if (k > 2)
; // FIXME: dst.
zone_number = 0; // FIXME: dst.
// FIXME: raw offset to SimpleTimeZone const.
calendar.setTimeZone(new SimpleTimeZone (1, strings[0]));
found_zone = true;
TimeZone tz = TimeZone.getTimeZone (strings[0]);
theCalendar.setTimeZone (tz);
theCalendar.clear (Calendar.DST_OFFSET);
theCalendar.clear (Calendar.ZONE_OFFSET);
pos.setIndex(index + strings[k].length());
break;
}
@ -690,15 +700,16 @@ public class SimpleDateFormat extends DateFormat
value = i;
}
else
value = zone_number;
value = 0;
// Assign the value and move on.
calendar.set(calendar_field, value);
if (calendar_field != Calendar.DST_OFFSET)
theCalendar.set(calendar_field, value);
}
try
{
return calendar.getTime();
return theCalendar.getTime();
}
catch (IllegalArgumentException x)
{
@ -706,4 +717,21 @@ public class SimpleDateFormat extends DateFormat
return null;
}
}
// Compute the start of the current century as defined by
// get2DigitYearStart.
private Date computeCenturyStart ()
{
// Compute the current year. We assume a year has 365 days. Then
// compute 80 years ago, and finally reconstruct the number of
// milliseconds. We do this computation in this strange way
// because it lets us easily truncate the milliseconds, seconds,
// etc, which don't matter and which confuse
// SimpleDateFormat.equals().
long now = System.currentTimeMillis ();
now /= 365L * 24L * 60L * 60L * 1000L;
now -= 80;
now *= 365L * 24L * 60L * 60L * 1000L;
return new Date (now);
}
}

View file

@ -1,5 +1,5 @@
/* java.util.Calendar
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@ -54,7 +54,7 @@ import java.io.*;
*
* When computing the date from time fields, it may happen, that there
* are either two few fields set, or some fields are inconsistent. This
* cases will handled in a calender specific way. Missing fields are
* cases will handled in a calendar specific way. Missing fields are
* replaced by the fields of the epoch: 1970 January 1 00:00. <br>
*
* To understand, how the day of year is computed out of the fields
@ -356,7 +356,7 @@ public abstract class Calendar implements Serializable, Cloneable
private static final String bundleName = "gnu.java.locale.Calendar";
/**
* Constructs a new Calender with the default time zone and the default
* Constructs a new Calendar with the default time zone and the default
* locale.
*/
protected Calendar()
@ -365,7 +365,7 @@ public abstract class Calendar implements Serializable, Cloneable
}
/**
* Constructs a new Calender with the given time zone and the given
* Constructs a new Calendar with the given time zone and the given
* locale.
* @param zone a time zone.
* @param locale a locale.
@ -483,7 +483,7 @@ public abstract class Calendar implements Serializable, Cloneable
}
/**
* Sets this Calender's time to the given Date. All time fields
* Sets this Calendar's time to the given Date. All time fields
* are invalidated by this method.
*/
public final void setTime(Date date)
@ -503,7 +503,7 @@ public abstract class Calendar implements Serializable, Cloneable
}
/**
* Sets this Calender's time to the given Time. All time fields
* Sets this Calendar's time to the given Time. All time fields
* are invalidated by this method.
* @param time the time in milliseconds since the epoch
*/
@ -522,6 +522,9 @@ public abstract class Calendar implements Serializable, Cloneable
*/
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 implements Serializable, Cloneable
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 implements Serializable, Cloneable
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 implements Serializable, Cloneable
fields[HOUR_OF_DAY] = hour;
fields[MINUTE] = minute;
isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
isSet[AM_PM] = false;
isSet[HOUR] = false;
}
/**
@ -611,7 +644,10 @@ public abstract class Calendar implements Serializable, Cloneable
isTimeSet = false;
areFieldsSet = false;
for (int i = 0; i < FIELD_COUNT; i++)
isSet[i] = false;
{
isSet[i] = false;
fields[i] = 0;
}
}
/**
@ -623,6 +659,7 @@ public abstract class Calendar implements Serializable, Cloneable
isTimeSet = false;
areFieldsSet = false;
isSet[field] = false;
fields[field] = 0;
}
/**
@ -647,7 +684,7 @@ public abstract class Calendar implements Serializable, Cloneable
}
/**
* Compares the given calender with this.
* Compares the given calendar with this.
* @param o the object to that we should compare.
* @return true, if the given object is a calendar, that represents
* the same time (but doesn't neccessary have the same fields).
@ -670,10 +707,10 @@ public abstract class Calendar implements Serializable, Cloneable
}
/**
* Compares the given calender with this.
* Compares the given calendar with this.
* @param o the object to that we should compare.
* @return true, if the given object is a calendar, and this calendar
* represents a smaller time than the calender o.
* represents a smaller time than the calendar o.
* @exception ClassCastException if o is not an calendar.
* @since JDK1.2 you don't need to override this method
*/
@ -683,10 +720,10 @@ public abstract class Calendar implements Serializable, Cloneable
}
/**
* Compares the given calender with this.
* Compares the given calendar with this.
* @param o the object to that we should compare.
* @return true, if the given object is a calendar, and this calendar
* represents a bigger time than the calender o.
* represents a bigger time than the calendar o.
* @exception ClassCastException if o is not an calendar.
* @since JDK1.2 you don't need to override this method
*/
@ -866,7 +903,7 @@ public abstract class Calendar implements Serializable, Cloneable
* @since jdk1.2
*/
// FIXME: XXX: Not abstract in JDK 1.2.
// public abstract int getActualMinimum(int field);
public abstract int getActualMinimum(int field);
/**
* Gets the actual maximum value that is allowed for the specified field.
@ -876,7 +913,7 @@ public abstract class Calendar implements Serializable, Cloneable
* @since jdk1.2
*/
// FIXME: XXX: Not abstract in JDK 1.2.
// public abstract int getActualMaximum(int field);
public abstract int getActualMaximum(int field);
/**
* Return a clone of this object.

File diff suppressed because it is too large Load diff

View file

@ -1,159 +0,0 @@
/* Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#include <config.h>
#ifdef ECOS
#include <string.h>
#endif
#include <gcj/cni.h>
#include <java/util/TimeZone.h>
#include <java/util/GregorianCalendar.h>
#include <java/lang/IllegalArgumentException.h>
#include <time.h>
void
java::util::GregorianCalendar::computeTime ()
{
struct tm tim;
tim.tm_sec = elements(fields)[SECOND];
tim.tm_min = elements(fields)[MINUTE];
tim.tm_hour = elements(fields)[HOUR_OF_DAY];
tim.tm_mday = elements(fields)[DATE];
tim.tm_mon = elements(fields)[MONTH];
tim.tm_year = elements(fields)[YEAR] - 1900;
tim.tm_isdst = 0;
#ifndef ECOS
// FIXME: None of the standard C library access to the ECOS calendar
// is yet available.
time_t t = mktime (&tim);
if (!isLenient ())
{
// mktime will correct for any time leniencies (e.g. 31-Apr becomes
// 1-May).
// Daylight savings time is a special case since times in hour 23
// will compute to hour 0 of the next day.
if (tim.tm_isdst == 0 || elements(fields)[HOUR_OF_DAY] != 23)
{
if (tim.tm_sec != elements(fields)[SECOND] ||
tim.tm_min != elements(fields)[MINUTE] ||
tim.tm_hour != elements(fields)[HOUR_OF_DAY] +
(tim.tm_isdst > 0 ? 1 : 0) ||
tim.tm_mday != elements(fields)[DATE] ||
tim.tm_mon != elements(fields)[MONTH] ||
tim.tm_year != elements(fields)[YEAR] - 1900)
throw new java::lang::IllegalArgumentException ();
}
else
{
// The easiest thing to do is to temporarily shift the clock
// back from the 23th hour so mktime doesn't cause the extra
// hour for DST to roll the date to the next day.
struct tm tmp_tim;
tmp_tim.tm_sec = elements(fields)[SECOND];
tmp_tim.tm_min = elements(fields)[MINUTE];
tmp_tim.tm_hour = elements(fields)[HOUR_OF_DAY] - 1;
tmp_tim.tm_mday = elements(fields)[DATE];
tmp_tim.tm_mon = elements(fields)[MONTH];
tmp_tim.tm_year = elements(fields)[YEAR] - 1900;
tmp_tim.tm_isdst = 0;
mktime (&tmp_tim);
if (tmp_tim.tm_sec != elements(fields)[SECOND] ||
tmp_tim.tm_min != elements(fields)[MINUTE] ||
tmp_tim.tm_hour != elements(fields)[HOUR_OF_DAY] ||
tmp_tim.tm_mday != elements(fields)[DATE] ||
tmp_tim.tm_mon != elements(fields)[MONTH] ||
tmp_tim.tm_year != elements(fields)[YEAR] - 1900)
throw new java::lang::IllegalArgumentException ();
}
}
#else
time_t t = 0;
#endif
// Adjust for local timezone (introduced by mktime) and our
// timezone.
#if defined (STRUCT_TM_HAS_GMTOFF)
t -= tim.tm_gmtoff;
#elif defined (HAVE_TIMEZONE)
t += timezone;
#endif
// Adjust for milliseconds.
time = t * (jlong) 1000 + elements(fields)[MILLISECOND];
// Now adjust for the real timezone, i.e. our timezone, which is in millis.
java::util::TimeZone *zone = getTimeZone ();
time += zone->getRawOffset();
isTimeSet = true;
}
void
java::util::GregorianCalendar::computeFields ()
{
time_t t = time / 1000;
int millis = time % 1000;
if (t < 0 && millis != 0)
{
t--;
millis = t - 1000 * t;
}
elements(fields)[MILLISECOND] = millis;
struct tm tim;
java::util::TimeZone *zone = getTimeZone ();
// FIXME: None of the standard C library access to the ECOS calendar
// is yet available.
#ifdef ECOS
memset (&tim, 0, sizeof tim);
#else
if (zone->getRawOffset() == 0 || ! zone->useDaylightTime())
{
#if defined(__JV_POSIX_THREADS__) && defined(HAVE_GMTIME_R)
gmtime_r (&t, &tim);
#else
// Get global lock (because gmtime uses a global buffer). FIXME
tim = *(struct tm*) gmtime (&t);
// Release global lock. FIXME
#endif
}
else
{
#if defined(__JV_POSIX_THREADS__) && defined(HAVE_LOCALTIME_R)
localtime_r (&t, &tim);
#else
// Get global lock (because localtime uses a global buffer). FIXME
tim = *(struct tm*) localtime (&t);
// Release global lock. FIXME
#endif
}
#endif /* ECOS */
elements(fields)[SECOND] = tim.tm_sec;
elements(fields)[MINUTE] = tim.tm_min;
elements(fields)[HOUR_OF_DAY] = tim.tm_hour;
elements(fields)[AM_PM] = tim.tm_hour < 12 ? AM : PM;
elements(fields)[HOUR] = tim.tm_hour % 12;
elements(fields)[DATE] = tim.tm_mday;
elements(fields)[MONTH] = tim.tm_mon;
elements(fields)[YEAR] = 1900 + tim.tm_year;
elements(fields)[DAY_OF_WEEK] = tim.tm_wday + 1;
elements(fields)[DAY_OF_WEEK_IN_MONTH] = ((tim.tm_mday - 1) / 7) + 1;
elements(fields)[DAY_OF_YEAR] = tim.tm_yday + 1;
elements(fields)[WEEK_OF_MONTH]
= (tim.tm_mday + 6 + (5 - tim.tm_wday + getFirstDayOfWeek()) % 7) / 7;
elements(fields)[WEEK_OF_YEAR]
= (tim.tm_yday + 7 + (5 - tim.tm_wday + getFirstDayOfWeek()) % 7) / 7;
elements(fields)[ERA] = AD;
elements(fields)[DST_OFFSET] = tim.tm_isdst <= 0 ? 0 : 60*60*1000;
elements(fields)[ZONE_OFFSET] = getTimeZone()->getRawOffset();
areFieldsSet = true;
for (int i = 0; i < FIELD_COUNT; i++)
elements(isSet__)[i] = true;
}