From: gary Date: Wed, 21 Feb 2007 13:49:01 +0000 (+0000) Subject: 2007-02-21 Gary Benson X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=0a1a9d848e8cb61a94a27b770009f2af2ceee351;hp=47079da24280fa2089352202c07f7689e850b7aa 2007-02-21 Gary Benson * java/util/GregorianCalendar.java: Removed. * sources.am, Makefile.in: Rebuilt. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122198 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 088f5eb7908..34c18cffcfd 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,8 @@ +2007-02-21 Gary Benson + + * java/util/GregorianCalendar.java: Removed. + * sources.am, Makefile.in: Rebuilt. + 2007-02-20 Keith Seitz * gnu/classpath/jdwp/natVMVirtualMachine.cc diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 16abe2df57a..db8813ed19b 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -4880,7 +4880,7 @@ classpath/java/util/Formattable.java \ classpath/java/util/FormattableFlags.java \ classpath/java/util/Formatter.java \ classpath/java/util/FormatterClosedException.java \ -java/util/GregorianCalendar.java \ +classpath/java/util/GregorianCalendar.java \ classpath/java/util/HashMap.java \ classpath/java/util/HashSet.java \ classpath/java/util/Hashtable.java \ diff --git a/libjava/classpath/lib/java/util/GregorianCalendar.class b/libjava/classpath/lib/java/util/GregorianCalendar.class index 00022634a16..1bda39e7ebb 100644 Binary files a/libjava/classpath/lib/java/util/GregorianCalendar.class and b/libjava/classpath/lib/java/util/GregorianCalendar.class differ diff --git a/libjava/java/util/GregorianCalendar.h b/libjava/java/util/GregorianCalendar.h index 46fb48e0133..9fe77cde5a0 100644 --- a/libjava/java/util/GregorianCalendar.h +++ b/libjava/java/util/GregorianCalendar.h @@ -61,7 +61,6 @@ private: public: // actually package-private static const jlong serialVersionUID = -8125100834729963327LL; private: - static ::java::lang::String * bundleName; static const jint EPOCH_DAYS = 719162; static JArray< jint > * minimums; static JArray< jint > * maximums; diff --git a/libjava/java/util/GregorianCalendar.java b/libjava/java/util/GregorianCalendar.java deleted file mode 100644 index dc77c2f5024..00000000000 --- a/libjava/java/util/GregorianCalendar.java +++ /dev/null @@ -1,1358 +0,0 @@ -/* java.util.GregorianCalendar - Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.util; - - -/** - *

- * This class represents the Gregorian calendar, that is used in most - * countries all over the world. It does also handle the Julian calendar - * for dates smaller than the date of the change to the Gregorian calendar. - * The Gregorian calendar differs from the Julian calendar by a different - * leap year rule (no leap year every 100 years, except if year is divisible - * by 400). - *

- *

- * This change date is different from country to country, and can be changed with - * setGregorianChange. The first countries to adopt the Gregorian - * calendar did so on the 15th of October, 1582. This date followed October - * the 4th, 1582 in the Julian calendar system. The non-existant days that were - * omitted when the change took place are interpreted as Gregorian dates. - *

- *

- * Prior to the changeover date, New Year's Day occurred on the 25th of March. - * However, this class always takes New Year's Day as being the 1st of January. - * Client code should manually adapt the year value, if required, for dates - * between January the 1st and March the 24th in years prior to the changeover. - *

- *

- * Any date infinitely forwards or backwards in time can be represented by - * this class. A proleptic calendar system is used, which allows - * future dates to be created via the existing rules. This allows meaningful - * and consistent dates to be produced for all years. However, dates are only - * historically accurate following March the 1st, 4AD when the Julian calendar - * system was adopted. Prior to this, leap year rules were applied erraticly. - *

- *

- * There are two eras available for the Gregorian calendar, namely BC and AD. - *

- *

- * Weeks are defined as a period of seven days, beginning on the first day - * of the week, as returned by getFirstDayOfWeek(), and ending - * on the day prior to this. - *

- *

- * The weeks of the year are numbered from 1 to a possible 53. The first week - * of the year is defined as the first week that contains at least the minimum - * number of days of the first week in the new year (retrieved via - * getMinimalDaysInFirstWeek()). All weeks after this are numbered - * from 2 onwards. - *

- *

- * For example, take the year 2004. It began on a Thursday. The first week - * of 2004 depends both on where a week begins and how long it must minimally - * last. Let's say that the week begins on a Monday and must have a minimum - * of 5 days. In this case, the first week begins on Monday, the 5th of January. - * The first 4 days (Thursday to Sunday) are not eligible, as they are too few - * to make up the minimum number of days of the first week which must be in - * the new year. If the minimum was lowered to 4 days, then the first week - * would instead begin on Monday, the 29th of December, 2003. This first week - * has 4 of its days in the new year, and is now eligible. - *

- *

- * The weeks of the month are numbered from 0 to a possible 6. The first week - * of the month (numbered 1) is a set of days, prior to the first day of the week, - * which number at least the minimum number of days in a week. Unlike the first - * week of the year, the first week of the month only uses days from that particular - * month. As a consequence, it may have a variable number of days (from the minimum - * number required up to a full week of 7) and it need not start on the first day of - * the week. It must, however, be following by the first day of the week, as this - * marks the beginning of week 2. Any days of the month which occur prior to the - * first week (because the first day of the week occurs before the minimum number - * of days is met) are seen as week 0. - *

- *

- * Again, we will take the example of the year 2004 to demonstrate this. September - * 2004 begins on a Wednesday. Taking our first day of the week as Monday, and the - * minimum length of the first week as 6, we find that week 1 runs from Monday, - * the 6th of September to Sunday the 12th. Prior to the 6th, there are only - * 5 days (Wednesday through to Sunday). This is too small a number to meet the - * minimum, so these are classed as being days in week 0. Week 2 begins on the - * 13th, and so on. This changes if we reduce the minimum to 5. In this case, - * week 1 is a truncated week from Wednesday the 1st to Sunday the 5th, and week - * 0 doesn't exist. The first seven day week is week 2, starting on the 6th. - *

- *

- * On using the clear() method, the Gregorian calendar returns - * to its default value of the 1st of January, 1970 AD 00:00:00 (the epoch). - * The day of the week is set to the correct day for that particular time. - * The day is also the first of the month, and the date is in week 0. - *

- * - * @see Calendar - * @see TimeZone - * @see Calendar#getFirstDayOfWeek() - * @see Calendar#getMinimalDaysInFirstWeek() - */ -public class GregorianCalendar extends Calendar -{ - /** - * Constant representing the era BC (Before Christ). - */ - public static final int BC = 0; - - /** - * Constant representing the era AD (Anno Domini). - */ - public static final int AD = 1; - - /** - * The point at which the Gregorian calendar rules were used. - * This is locale dependent; the default for most catholic - * countries is midnight (UTC) on October 5, 1582 (Julian), - * or October 15, 1582 (Gregorian). - * - * @serial the changeover point from the Julian calendar - * system to the Gregorian. - */ - private long gregorianCutover; - - /** - * For compatability with Sun's JDK. - */ - static final long serialVersionUID = -8125100834729963327L; - - /** - * The name of the resource bundle. Used only by getBundle() - */ - private static final String bundleName = "gnu.java.locale.Calendar"; - - /** - * Days in the epoch. Relative Jan 1, year '0' which is not a leap year. - * (although there is no year zero, this does not matter.) - * This is consistent with the formula: - * = (year-1)*365L + ((year-1) >> 2) - * - * Plus the gregorian correction: - * Math.floor((year-1) / 400.) - Math.floor((year-1) / 100.); - * For a correct julian date, the correction is -2 instead. - * - * The gregorian cutover in 1582 was 10 days, so by calculating the - * correction from year zero, we have 15 non-leap days (even centuries) - * minus 3 leap days (year 400,800,1200) = 12. Subtracting two corrects - * this to the correct number 10. - */ - private static final int EPOCH_DAYS = 719162; - - /** - * Constructs a new GregorianCalender representing the current - * time, using the default time zone and the default locale. - */ - public GregorianCalendar() - { - this(TimeZone.getDefault(), Locale.getDefault()); - } - - /** - * Constructs a new GregorianCalender representing the current - * time, using the specified time zone and the default locale. - * - * @param zone a time zone. - */ - public GregorianCalendar(TimeZone zone) - { - this(zone, Locale.getDefault()); - } - - /** - * Constructs a new GregorianCalender representing the current - * time, using the default time zone and the specified locale. - * - * @param locale a locale. - */ - public GregorianCalendar(Locale locale) - { - this(TimeZone.getDefault(), locale); - } - - /** - * Constructs a new GregorianCalender representing the current - * time with the given time zone and the given locale. - * - * @param zone a time zone. - * @param locale a locale. - */ - public GregorianCalendar(TimeZone zone, Locale locale) - { - this(zone, locale, false); - setTimeInMillis(System.currentTimeMillis()); - complete(); - } - - /** - * Common constructor that all constructors should call. - * @param zone a time zone. - * @param locale a locale. - * @param unused unused parameter to make the signature differ from - * the public constructor (TimeZone, Locale). - */ - private GregorianCalendar(TimeZone zone, Locale locale, boolean unused) - { - super(zone, locale); - ResourceBundle rb = ResourceBundle.getBundle(bundleName, locale, - ClassLoader - .getSystemClassLoader()); - gregorianCutover = ((Date) rb.getObject("gregorianCutOver")).getTime(); - } - - /** - * 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. - */ - public GregorianCalendar(int year, int month, int day) - { - this(TimeZone.getDefault(), Locale.getDefault(), false); - set(year, month, day); - } - - /** - * 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. - * @param hour corresponds to the HOUR_OF_DAY time field. - * @param minute corresponds to the MINUTE time field. - */ - public GregorianCalendar(int year, int month, int day, int hour, int minute) - { - this(TimeZone.getDefault(), Locale.getDefault(), false); - set(year, month, day, hour, minute); - } - - /** - * 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. - * @param hour corresponds to the HOUR_OF_DAY time field. - * @param minute corresponds to the MINUTE time field. - * @param second corresponds to the SECOND time field. - */ - public GregorianCalendar(int year, int month, int day, int hour, int minute, - int second) - { - this(TimeZone.getDefault(), Locale.getDefault(), false); - set(year, month, day, hour, minute, second); - } - - /** - * Sets the date of the switch from Julian dates to Gregorian dates. - * You can use new Date(Long.MAX_VALUE) to use a pure - * Julian calendar, or Long.MIN_VALUE for a pure Gregorian - * calendar. - * - * @param date the date of the change. - */ - public void setGregorianChange(Date date) - { - gregorianCutover = date.getTime(); - } - - /** - * Gets the date of the switch from Julian dates to Gregorian dates. - * - * @return the date of the change. - */ - public final Date getGregorianChange() - { - return new Date(gregorianCutover); - } - - /** - *

- * Determines if the given year is a leap year. The result is - * undefined if the Gregorian change took place in 1800, so that - * the end of February is skipped, and that year is specified. - * (well...). - *

- *

- * To specify a year in the BC era, use a negative value calculated - * as 1 - y, where y is the required year in BC. So, 1 BC is 0, - * 2 BC is -1, 3 BC is -2, etc. - *

- * - * @param year a year (use a negative value for BC). - * @return true, if the given year is a leap year, false otherwise. - */ - public boolean isLeapYear(int year) - { - // Only years divisible by 4 can be leap years - if ((year & 3) != 0) - return false; - - // Is the leap-day a Julian date? Then it's a leap year - if (! isGregorian(year, 31 + 29 - 1)) - return true; - - // Apply gregorian rules otherwise - return ((year % 100) != 0 || (year % 400) == 0); - } - - /** - * Retrieves the day of the week corresponding to the specified - * day of the specified year. - * - * @param year the year in which the dayOfYear occurs. - * @param dayOfYear the day of the year (an integer between 0 and - * and 366) - */ - private int getWeekDay(int year, int dayOfYear) - { - boolean greg = isGregorian(year, dayOfYear); - int day = (int) getLinearDay(year, dayOfYear, greg); - - // The epoch was a thursday. - int weekday = (day + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - return weekday; - } - - /** - * Returns the day of the week for the first day of a given month (0..11) - */ - private int getFirstDayOfMonth(int year, int month) - { - int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - - if (month > 11) - { - year += (month / 12); - month = month % 12; - } - - if (month < 0) - { - year += (int) month / 12; - month = month % 12; - if (month < 0) - { - month += 12; - year--; - } - } - - int dayOfYear = dayCount[month] + 1; - if (month > 1) - if (isLeapYear(year)) - dayOfYear++; - - boolean greg = isGregorian(year, dayOfYear); - int day = (int) getLinearDay(year, dayOfYear, greg); - - // The epoch was a thursday. - int weekday = (day + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - return weekday; - } - - /** - * Takes a year, and a (zero based) day of year and determines - * if it is gregorian or not. - */ - private boolean isGregorian(int year, int dayOfYear) - { - int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear - - EPOCH_DAYS; // gregorian days from 1 to epoch. - int gregFactor = (int) Math.floor((double) (year - 1) / 400.) - - (int) Math.floor((double) (year - 1) / 100.); - - return ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover); - } - - /** - * Check set fields for validity, without leniency. - * - * @throws IllegalArgumentException if a field is invalid - */ - private void nonLeniencyCheck() throws IllegalArgumentException - { - int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - int year = fields[YEAR]; - int month = fields[MONTH]; - int leap = isLeapYear(year) ? 1 : 0; - - if (isSet[ERA] && fields[ERA] != AD && fields[ERA] != BC) - throw new IllegalArgumentException("Illegal ERA."); - if (isSet[YEAR] && fields[YEAR] < 1) - throw new IllegalArgumentException("Illegal YEAR."); - if (isSet[MONTH] && (month < 0 || month > 11)) - throw new IllegalArgumentException("Illegal MONTH."); - if (isSet[WEEK_OF_YEAR]) - { - int daysInYear = 365 + leap; - daysInYear += (getFirstDayOfMonth(year, 0) - 1); // pad first week - int last = getFirstDayOfMonth(year, 11) + 4; - if (last > 7) - last -= 7; - daysInYear += 7 - last; - int weeks = daysInYear / 7; - if (fields[WEEK_OF_YEAR] < 1 || fields[WEEK_OF_YEAR] > weeks) - throw new IllegalArgumentException("Illegal WEEK_OF_YEAR."); - } - - if (isSet[WEEK_OF_MONTH]) - { - int weeks = (month == 1 && leap == 0) ? 4 : 5; - if (fields[WEEK_OF_MONTH] < 1 || fields[WEEK_OF_MONTH] > weeks) - throw new IllegalArgumentException("Illegal WEEK_OF_MONTH."); - } - - if (isSet[DAY_OF_MONTH]) - if (fields[DAY_OF_MONTH] < 1 - || fields[DAY_OF_MONTH] > month_days[month] - + ((month == 1) ? leap : 0)) - throw new IllegalArgumentException("Illegal DAY_OF_MONTH."); - - if (isSet[DAY_OF_YEAR] - && (fields[DAY_OF_YEAR] < 1 || fields[DAY_OF_YEAR] > 365 + leap)) - throw new IllegalArgumentException("Illegal DAY_OF_YEAR."); - - if (isSet[DAY_OF_WEEK] - && (fields[DAY_OF_WEEK] < 1 || fields[DAY_OF_WEEK] > 7)) - throw new IllegalArgumentException("Illegal DAY_OF_WEEK."); - - if (isSet[DAY_OF_WEEK_IN_MONTH]) - { - int weeks = (month == 1 && leap == 0) ? 4 : 5; - if (fields[DAY_OF_WEEK_IN_MONTH] < -weeks - || fields[DAY_OF_WEEK_IN_MONTH] > weeks) - throw new IllegalArgumentException("Illegal DAY_OF_WEEK_IN_MONTH."); - } - - 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] > 11)) - throw new IllegalArgumentException("Illegal HOUR."); - if (isSet[HOUR_OF_DAY] - && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23)) - throw new IllegalArgumentException("Illegal HOUR_OF_DAY."); - if (isSet[MINUTE] && (fields[MINUTE] < 0 || fields[MINUTE] > 59)) - throw new IllegalArgumentException("Illegal MINUTE."); - if (isSet[SECOND] && (fields[SECOND] < 0 || fields[SECOND] > 59)) - throw new IllegalArgumentException("Illegal SECOND."); - if (isSet[MILLISECOND] - && (fields[MILLISECOND] < 0 || fields[MILLISECOND] > 999)) - throw new IllegalArgumentException("Illegal MILLISECOND."); - if (isSet[ZONE_OFFSET] - && (fields[ZONE_OFFSET] < -12 * 60 * 60 * 1000L - || fields[ZONE_OFFSET] > 12 * 60 * 60 * 1000L)) - throw new IllegalArgumentException("Illegal ZONE_OFFSET."); - if (isSet[DST_OFFSET] - && (fields[DST_OFFSET] < -12 * 60 * 60 * 1000L - || fields[DST_OFFSET] > 12 * 60 * 60 * 1000L)) - throw new IllegalArgumentException("Illegal DST_OFFSET."); - } - - /** - * Converts the time field values (fields) to - * milliseconds since the epoch UTC (time). - * - * @throws IllegalArgumentException if any calendar fields - * are invalid. - */ - protected synchronized void computeTime() - { - int millisInDay = 0; - int era = fields[ERA]; - int year = fields[YEAR]; - int month = fields[MONTH]; - int day = fields[DAY_OF_MONTH]; - - int minute = fields[MINUTE]; - int second = fields[SECOND]; - int millis = fields[MILLISECOND]; - int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - int hour = 0; - - if (! isLenient()) - nonLeniencyCheck(); - - if (! isSet[MONTH] && (! isSet[DAY_OF_WEEK] || isSet[WEEK_OF_YEAR])) - { - // 5: YEAR + DAY_OF_WEEK + WEEK_OF_YEAR - if (isSet[WEEK_OF_YEAR]) - { - int first = getFirstDayOfMonth(year, 0); - int offs = 1; - int daysInFirstWeek = getFirstDayOfWeek() - first; - if (daysInFirstWeek <= 0) - daysInFirstWeek += 7; - - if (daysInFirstWeek < getMinimalDaysInFirstWeek()) - offs += daysInFirstWeek; - else - offs -= 7 - daysInFirstWeek; - month = 0; - day = offs + 7 * (fields[WEEK_OF_YEAR] - 1); - offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); - - if (offs < 0) - offs += 7; - day += offs; - } - else - { - // 4: YEAR + DAY_OF_YEAR - month = 0; - day = fields[DAY_OF_YEAR]; - } - } - else - { - if (isSet[DAY_OF_WEEK]) - { - int first = getFirstDayOfMonth(year, month); - - // 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 += offs; - } - else - { // 2: YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK - int offs = 1; - int daysInFirstWeek = getFirstDayOfWeek() - first; - if (daysInFirstWeek <= 0) - daysInFirstWeek += 7; - - if (daysInFirstWeek < getMinimalDaysInFirstWeek()) - offs += daysInFirstWeek; - else - offs -= 7 - daysInFirstWeek; - - day = offs + 7 * (fields[WEEK_OF_MONTH] - 1); - offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek(); - if (offs <= 0) - offs += 7; - day += offs; - } - } - - // 1: YEAR + MONTH + DAY_OF_MONTH - } - if (era == BC && year > 0) - year = 1 - year; - - // rest of code assumes day/month/year set - // should negative BC years be AD? - // get the hour (but no check for validity) - if (isSet[HOUR]) - { - hour = fields[HOUR]; - if (fields[AM_PM] == PM) - hour += 12; - } - else - hour = fields[HOUR_OF_DAY]; - - // Read the era,year,month,day fields and convert as appropriate. - // Calculate number of milliseconds into the day - // This takes care of both h, m, s, ms over/underflows. - long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L + millis; - day += allMillis / (24 * 60 * 60 * 1000L); - millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L)); - - if (month < 0) - { - year += (int) month / 12; - month = month % 12; - if (month < 0) - { - month += 12; - year--; - } - } - if (month > 11) - { - year += (month / 12); - month = month % 12; - } - - month_days[1] = isLeapYear(year) ? 29 : 28; - - while (day <= 0) - { - if (month == 0) - { - year--; - month_days[1] = isLeapYear(year) ? 29 : 28; - } - month = (month + 11) % 12; - day += month_days[month]; - } - while (day > month_days[month]) - { - day -= (month_days[month]); - month = (month + 1) % 12; - if (month == 0) - { - year++; - month_days[1] = isLeapYear(year) ? 29 : 28; - } - } - - // ok, by here we have valid day,month,year,era and millisinday - int dayOfYear = dayCount[month] + day - 1; // (day starts on 1) - if (isLeapYear(year) && month > 1) - dayOfYear++; - - int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear - - EPOCH_DAYS; // gregorian days from 1 to epoch. - int gregFactor = (int) Math.floor((double) (year - 1) / 400.) - - (int) Math.floor((double) (year - 1) / 100.); - - if ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover) - relativeDay += gregFactor; - else - relativeDay -= 2; - - time = relativeDay * (24 * 60 * 60 * 1000L) + millisInDay; - - // the epoch was a Thursday. - int weekday = (int) (relativeDay + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - fields[DAY_OF_WEEK] = weekday; - - // Time zone corrections. - TimeZone zone = getTimeZone(); - int rawOffset = isSet[ZONE_OFFSET] ? fields[ZONE_OFFSET] - : zone.getRawOffset(); - - int dstOffset = isSet[DST_OFFSET] ? fields[DST_OFFSET] - : (zone.getOffset((year < 0) ? BC : AD, - (year < 0) ? 1 - year - : year, - month, day, weekday, - millisInDay) - - zone.getRawOffset()); - - time -= rawOffset + dstOffset; - - isTimeSet = true; - } - - /** - * Get the linear day in days since the epoch, using the - * Julian or Gregorian calendar as specified. If you specify a - * nonpositive year it is interpreted as BC as following: 0 is 1 - * BC, -1 is 2 BC and so on. - * - * @param year the year of the date. - * @param dayOfYear the day of year of the date; 1 based. - * @param gregorian true, if we should use the Gregorian rules. - * @return the days since the epoch, may be negative. - */ - 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 - // with respect to julian calendar. - // - // Okay, here we rely on the fact that the gregorian - // calendar was introduced in the AD era. This doesn't work - // with negative years. - // - // The additional leap year factor accounts for the fact that - // a leap day is not seen on Jan 1 of the leap year. - int gregOffset = (int) Math.floor((double) (year - 1) / 400.) - - (int) Math.floor((double) (year - 1) / 100.); - - return julianDay + gregOffset; - } - else - julianDay -= 2; - return julianDay; - } - - /** - * Converts the given linear day into era, year, month, - * day_of_year, day_of_month, day_of_week, and writes the result - * into the fields array. - * - * @param day the linear day. - * @param gregorian true, if we should use Gregorian rules. - */ - private void calculateDay(int[] fields, long day, boolean gregorian) - { - // the epoch was a Thursday. - int weekday = (int) (day + THURSDAY) % 7; - if (weekday <= 0) - weekday += 7; - fields[DAY_OF_WEEK] = weekday; - - // get a first approximation of the year. This may be one - // year too big. - int year = 1970 - + (int) (gregorian - ? ((day - 100L) * 400L) / (365L * 400L + 100L - 4L - + 1L) : ((day - 100L) * 4L) / (365L * 4L + 1L)); - if (day >= 0) - year++; - - long firstDayOfYear = getLinearDay(year, 1, gregorian); - - // Now look in which year day really lies. - if (day < firstDayOfYear) - { - year--; - firstDayOfYear = getLinearDay(year, 1, gregorian); - } - - day -= firstDayOfYear - 1; // day of year, one based. - - fields[DAY_OF_YEAR] = (int) day; - if (year <= 0) - { - fields[ERA] = BC; - fields[YEAR] = 1 - year; - } - else - { - fields[ERA] = AD; - fields[YEAR] = year; - } - - int leapday = isLeapYear(year) ? 1 : 0; - if (day <= 31 + 28 + leapday) - { - fields[MONTH] = (int) day / 32; // 31->JANUARY, 32->FEBRUARY - fields[DAY_OF_MONTH] = (int) day - 31 * fields[MONTH]; - } - else - { - // A few more magic formulas - int scaledDay = ((int) day - leapday) * 5 + 8; - fields[MONTH] = scaledDay / (31 + 30 + 31 + 30 + 31); - fields[DAY_OF_MONTH] = (scaledDay % (31 + 30 + 31 + 30 + 31)) / 5 + 1; - } - } - - /** - * Converts the milliseconds since the epoch UTC - * (time) to time fields - * (fields). - */ - protected synchronized void computeFields() - { - boolean gregorian = (time >= gregorianCutover); - - TimeZone zone = getTimeZone(); - fields[ZONE_OFFSET] = zone.getRawOffset(); - long localTime = time + fields[ZONE_OFFSET]; - - long day = localTime / (24 * 60 * 60 * 1000L); - int millisInDay = (int) (localTime % (24 * 60 * 60 * 1000L)); - - if (millisInDay < 0) - { - millisInDay += (24 * 60 * 60 * 1000); - day--; - } - - calculateDay(fields, day, gregorian); - fields[DST_OFFSET] = zone.getOffset(fields[ERA], fields[YEAR], - fields[MONTH], fields[DAY_OF_MONTH], - fields[DAY_OF_WEEK], millisInDay) - - fields[ZONE_OFFSET]; - - millisInDay += fields[DST_OFFSET]; - if (millisInDay >= 24 * 60 * 60 * 1000) - { - millisInDay -= 24 * 60 * 60 * 1000; - calculateDay(fields, ++day, gregorian); - } - - fields[DAY_OF_WEEK_IN_MONTH] = (fields[DAY_OF_MONTH] + 6) / 7; - - // which day of the week are we (0..6), relative to getFirstDayOfWeek - int relativeWeekday = (7 + fields[DAY_OF_WEEK] - getFirstDayOfWeek()) % 7; - - fields[WEEK_OF_MONTH] = (fields[DAY_OF_MONTH] - relativeWeekday + 12) / 7; - - int weekOfYear = (fields[DAY_OF_YEAR] - relativeWeekday + 6) / 7; - - // Do the Correction: getMinimalDaysInFirstWeek() is always in the - // first week. - int minDays = getMinimalDaysInFirstWeek(); - int firstWeekday = (7 + getWeekDay(fields[YEAR], minDays) - - getFirstDayOfWeek()) % 7; - if (minDays - firstWeekday < 1) - weekOfYear++; - fields[WEEK_OF_YEAR] = weekOfYear; - - int hourOfDay = millisInDay / (60 * 60 * 1000); - fields[AM_PM] = (hourOfDay < 12) ? AM : PM; - int hour = hourOfDay % 12; - fields[HOUR] = hour; - fields[HOUR_OF_DAY] = hourOfDay; - millisInDay %= (60 * 60 * 1000); - fields[MINUTE] = millisInDay / (60 * 1000); - millisInDay %= (60 * 1000); - fields[SECOND] = millisInDay / (1000); - fields[MILLISECOND] = millisInDay % 1000; - - areFieldsSet = isSet[ERA] = isSet[YEAR] = isSet[MONTH] = isSet[WEEK_OF_YEAR] = isSet[WEEK_OF_MONTH] = isSet[DAY_OF_MONTH] = isSet[DAY_OF_YEAR] = isSet[DAY_OF_WEEK] = isSet[DAY_OF_WEEK_IN_MONTH] = isSet[AM_PM] = isSet[HOUR] = isSet[HOUR_OF_DAY] = isSet[MINUTE] = isSet[SECOND] = isSet[MILLISECOND] = isSet[ZONE_OFFSET] = isSet[DST_OFFSET] = true; - } - - /** - * Return a hash code for this object, following the general contract - * specified by {@link Object#hashCode()}. - * @return the hash code - */ - public int hashCode() - { - int val = (int) ((gregorianCutover >>> 32) ^ (gregorianCutover & 0xffffffff)); - return super.hashCode() ^ val; - } - - /** - * Compares the given calendar with this. An object, o, is - * equivalent to this if it is also a GregorianCalendar - * with the same time since the epoch under the same conditions - * (same change date and same time zone). - * - * @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 necessarily have the same fields). - * @throws IllegalArgumentException if one of the fields - * ZONE_OFFSET or DST_OFFSET is - * specified, if an unknown field is specified or if one - * of the calendar fields receives an illegal value when - * leniancy is not enabled. - */ - public boolean equals(Object o) - { - if (! (o instanceof GregorianCalendar)) - return false; - - GregorianCalendar cal = (GregorianCalendar) o; - return (cal.gregorianCutover == gregorianCutover - && super.equals(o)); - } - - /** - * Adds the specified amount of time to the given time field. The - * amount may be negative to subtract the time. If the field overflows - * it does what you expect: Jan, 25 + 10 Days is Feb, 4. - * @param field one of the time field constants. - * @param amount the amount of time to add. - * @exception IllegalArgumentException if field is - * ZONE_OFFSET, DST_OFFSET, or invalid; or - * if amount contains an out-of-range value and the calendar - * is not in lenient mode. - */ - public void add(int field, int amount) - { - switch (field) - { - case YEAR: - complete(); - fields[YEAR] += amount; - isTimeSet = false; - break; - case MONTH: - complete(); - int months = fields[MONTH] + amount; - fields[YEAR] += months / 12; - fields[MONTH] = months % 12; - if (fields[MONTH] < 0) - { - fields[MONTH] += 12; - fields[YEAR]--; - } - int maxDay = getActualMaximum(DAY_OF_MONTH); - if (fields[DAY_OF_MONTH] > maxDay) - fields[DAY_OF_MONTH] = maxDay; - set(YEAR, fields[YEAR]); - set(MONTH, fields[MONTH]); - break; - case DAY_OF_MONTH: - case DAY_OF_YEAR: - case DAY_OF_WEEK: - if (! isTimeSet) - computeTime(); - time += amount * (24 * 60 * 60 * 1000L); - areFieldsSet = false; - break; - case WEEK_OF_YEAR: - case WEEK_OF_MONTH: - case DAY_OF_WEEK_IN_MONTH: - if (! isTimeSet) - computeTime(); - time += amount * (7 * 24 * 60 * 60 * 1000L); - areFieldsSet = false; - break; - case AM_PM: - if (! isTimeSet) - computeTime(); - time += amount * (12 * 60 * 60 * 1000L); - areFieldsSet = false; - break; - case HOUR: - case HOUR_OF_DAY: - if (! isTimeSet) - computeTime(); - time += amount * (60 * 60 * 1000L); - areFieldsSet = false; - break; - case MINUTE: - if (! isTimeSet) - computeTime(); - time += amount * (60 * 1000L); - areFieldsSet = false; - break; - case SECOND: - if (! isTimeSet) - computeTime(); - time += amount * (1000L); - areFieldsSet = false; - break; - case MILLISECOND: - if (! isTimeSet) - computeTime(); - time += amount; - areFieldsSet = false; - break; - case ZONE_OFFSET: - case DST_OFFSET:default: - throw new IllegalArgumentException("Invalid or unknown field"); - } - } - - /** - * Rolls the specified time field up or down. This means add one - * to the specified field, but don't change the other fields. If - * the maximum for this field is reached, start over with the - * minimum value. - * - * Note: There may be situation, where the other - * fields must be changed, e.g rolling the month on May, 31. - * The date June, 31 is automatically converted to July, 1. - * This requires lenient settings. - * - * @param field the time field. One of the time field constants. - * @param up the direction, true for up, false for down. - * @throws IllegalArgumentException if one of the fields - * ZONE_OFFSET or DST_OFFSET is - * specified, if an unknown field is specified or if one - * of the calendar fields receives an illegal value when - * leniancy is not enabled. - */ - public void roll(int field, boolean up) - { - roll(field, up ? 1 : -1); - } - - /** - * Checks that the fields are still within their legal bounds, - * following use of the roll() method. - * - * @param field the field to check. - * @param delta multipler for alterations to the time. - * @see #roll(int, boolean) - * @see #roll(int, int) - */ - private void cleanUpAfterRoll(int field, int delta) - { - switch (field) - { - case ERA: - case YEAR: - case MONTH: - // check that day of month is still in correct range - if (fields[DAY_OF_MONTH] > getActualMaximum(DAY_OF_MONTH)) - fields[DAY_OF_MONTH] = getActualMaximum(DAY_OF_MONTH); - isTimeSet = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - break; - case DAY_OF_MONTH: - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (24 * 60 * 60 * 1000L); - break; - case WEEK_OF_MONTH: - isSet[DAY_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (7 * 24 * 60 * 60 * 1000L); - break; - case DAY_OF_WEEK_IN_MONTH: - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (7 * 24 * 60 * 60 * 1000L); - break; - case DAY_OF_YEAR: - isSet[MONTH] = false; - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_WEEK] = false; - isSet[WEEK_OF_YEAR] = false; - time += delta * (24 * 60 * 60 * 1000L); - break; - case WEEK_OF_YEAR: - isSet[MONTH] = false; - isSet[DAY_OF_MONTH] = false; - isSet[WEEK_OF_MONTH] = false; - isSet[DAY_OF_WEEK_IN_MONTH] = false; - isSet[DAY_OF_YEAR] = false; - time += delta * (7 * 24 * 60 * 60 * 1000L); - break; - case AM_PM: - isSet[HOUR_OF_DAY] = false; - time += delta * (12 * 60 * 60 * 1000L); - break; - case HOUR: - isSet[HOUR_OF_DAY] = false; - time += delta * (60 * 60 * 1000L); - break; - case HOUR_OF_DAY: - isSet[HOUR] = false; - isSet[AM_PM] = false; - time += delta * (60 * 60 * 1000L); - break; - case MINUTE: - time += delta * (60 * 1000L); - break; - case SECOND: - time += delta * (1000L); - break; - case MILLISECOND: - time += delta; - break; - } - } - - /** - * Rolls the specified time field by the given amount. This means - * add amount to the specified field, but don't change the other - * fields. If the maximum for this field is reached, start over - * with the minimum value and vice versa for negative amounts. - * - * Note: There may be situation, where the other - * fields must be changed, e.g rolling the month on May, 31. - * The date June, 31 is automatically corrected to June, 30. - * - * @param field the time field. One of the time field constants. - * @param amount the amount by which we should roll. - * @throws IllegalArgumentException if one of the fields - * ZONE_OFFSET or DST_OFFSET is - * specified, if an unknown field is specified or if one - * of the calendar fields receives an illegal value when - * leniancy is not enabled. - */ - public void roll(int field, int amount) - { - switch (field) - { - case DAY_OF_WEEK: - // day of week is special: it rolls automatically - add(field, amount); - return; - case ZONE_OFFSET: - case DST_OFFSET: - throw new IllegalArgumentException("Can't roll time zone"); - } - complete(); - int min = getActualMinimum(field); - int range = getActualMaximum(field) - min + 1; - int oldval = fields[field]; - int newval = (oldval - min + range + amount) % range + min; - if (newval < min) - newval += range; - fields[field] = newval; - cleanUpAfterRoll(field, newval - oldval); - } - - /** - * The minimum values for the calendar fields. - */ - private static final int[] minimums = - { - BC, 1, 0, 0, 1, 1, 1, SUNDAY, 1, AM, - 1, 0, 0, 0, 0, -(12 * 60 * 60 * 1000), - 0 - }; - - /** - * The maximum values for the calendar fields. - */ - private static final int[] maximums = - { - AD, 5000000, 11, 53, 5, 31, 366, - SATURDAY, 5, PM, 12, 23, 59, 59, 999, - +(12 * 60 * 60 * 1000), - (12 * 60 * 60 * 1000) - }; - - /** - * Gets the smallest value that is allowed for the specified field. - * - * @param field one of the time field constants. - * @return the smallest value for the specified field. - */ - public int getMinimum(int field) - { - return minimums[field]; - } - - /** - * Gets the biggest value that is allowed for the specified field. - * - * @param field one of the time field constants. - * @return the biggest value. - */ - public int getMaximum(int field) - { - return maximums[field]; - } - - /** - * Gets the greatest minimum value that is allowed for the specified field. - * This is the largest value returned by the getActualMinimum(int) - * method. - * - * @param field the time field. One of the time field constants. - * @return the greatest minimum value. - * @see #getActualMinimum(int) - */ - public int getGreatestMinimum(int field) - { - if (field == WEEK_OF_YEAR) - return 1; - return minimums[field]; - } - - /** - * Gets the smallest maximum value that is allowed for the - * specified field. This is the smallest value returned - * by the getActualMaximum(int). For example, - * this is 28 for DAY_OF_MONTH (as all months have at least - * 28 days). - * - * @param field the time field. One of the time field constants. - * @return the least maximum value. - * @see #getActualMaximum(int) - * @since 1.2 - */ - public int getLeastMaximum(int field) - { - switch (field) - { - case WEEK_OF_YEAR: - return 52; - case DAY_OF_MONTH: - return 28; - case DAY_OF_YEAR: - return 365; - case DAY_OF_WEEK_IN_MONTH: - case WEEK_OF_MONTH: - return 4; - default: - return maximums[field]; - } - } - - /** - * Gets the actual minimum value that is allowed for the specified field. - * This value is dependent on the values of the other fields. Note that - * this calls complete() if not enough fields are set. This - * can have ugly side effects. The value given depends on the current - * time used by this instance. - * - * @param field the time field. One of the time field constants. - * @return the actual minimum value. - * @since 1.2 - */ - public int getActualMinimum(int field) - { - if (field == WEEK_OF_YEAR) - { - int min = getMinimalDaysInFirstWeek(); - if (min == 0) - return 1; - if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR]) - complete(); - - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - int weekday = getWeekDay(year, min); - if ((7 + weekday - getFirstDayOfWeek()) % 7 >= min - 1) - return 1; - return 0; - } - return minimums[field]; - } - - /** - * Gets the actual maximum value that is allowed for the specified field. - * This value is dependent on the values of the other fields. Note that - * this calls complete() if not enough fields are set. This - * can have ugly side effects. The value given depends on the current time - * used by this instance; thus, leap years have a maximum day of month value of - * 29, rather than 28. - * - * @param field the time field. One of the time field constants. - * @return the actual maximum value. - */ - public int getActualMaximum(int field) - { - switch (field) - { - case WEEK_OF_YEAR: - { - if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR]) - complete(); - - // This is wrong for the year that contains the gregorian change. - // I.e it gives the weeks in the julian year or in the gregorian - // year in that case. - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - int lastDay = isLeapYear(year) ? 366 : 365; - int weekday = getWeekDay(year, lastDay); - int week = (lastDay + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7; - - int minimalDays = getMinimalDaysInFirstWeek(); - int firstWeekday = getWeekDay(year, minimalDays); - /* - * Is there a set of days at the beginning of the year, before the - * first day of the week, equal to or greater than the minimum number - * of days required in the first week? - */ - if (minimalDays - (7 + firstWeekday - getFirstDayOfWeek()) % 7 < 1) - return week + 1; /* Add week 1: firstWeekday through to firstDayOfWeek */ - } - case DAY_OF_MONTH: - { - if (! areFieldsSet || ! isSet[MONTH]) - complete(); - int month = fields[MONTH]; - - // If you change this, you should also change - // SimpleTimeZone.getDaysInMonth(); - if (month == FEBRUARY) - { - if (! isSet[YEAR] || ! isSet[ERA]) - complete(); - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - return isLeapYear(year) ? 29 : 28; - } - else if (month < AUGUST) - return 31 - (month & 1); - else - return 30 + (month & 1); - } - case DAY_OF_YEAR: - { - if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR]) - complete(); - int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR]; - return isLeapYear(year) ? 366 : 365; - } - case DAY_OF_WEEK_IN_MONTH: - { - // This is wrong for the month that contains the gregorian change. - int daysInMonth = getActualMaximum(DAY_OF_MONTH); - - // That's black magic, I know - return (daysInMonth - (fields[DAY_OF_MONTH] - 1) % 7 + 6) / 7; - } - case WEEK_OF_MONTH: - { - int daysInMonth = getActualMaximum(DAY_OF_MONTH); - int weekday = (daysInMonth - fields[DAY_OF_MONTH] - + fields[DAY_OF_WEEK] - SUNDAY) % 7 + SUNDAY; - return (daysInMonth + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7; - } - default: - return maximums[field]; - } - } -} diff --git a/libjava/sources.am b/libjava/sources.am index ce077f4c700..01618ce0c20 100644 --- a/libjava/sources.am +++ b/libjava/sources.am @@ -5525,7 +5525,7 @@ classpath/java/util/Formattable.java \ classpath/java/util/FormattableFlags.java \ classpath/java/util/Formatter.java \ classpath/java/util/FormatterClosedException.java \ -java/util/GregorianCalendar.java \ +classpath/java/util/GregorianCalendar.java \ classpath/java/util/HashMap.java \ classpath/java/util/HashSet.java \ classpath/java/util/Hashtable.java \