⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gregoriancalendar.java

📁 java源代码 请看看啊 提点宝贵的意见
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        } else {            // We handle most fields here.  The algorithm is to add a computed amount            // of millis to the current millis.  The only wrinkle is with DST -- if            // the result of the add operation is to move from DST to Standard, or vice            // versa, we need to adjust by an hour forward or back, respectively.            // Otherwise you get weird effects in which the hour seems to shift when            // you add to the DAY_OF_MONTH field, for instance.            // We only adjust the DST for fields larger than an hour.  For fields            // smaller than an hour, we cannot adjust for DST without causing problems.            // for instance, if you add one hour to April 5, 1998, 1:00 AM, in PST,            // the time becomes "2:00 AM PDT" (an illegal value), but then the adjustment            // sees the change and compensates by subtracting an hour.  As a result the            // time doesn't advance at all.            long delta = amount;            boolean adjustDST = true;            switch (field) {            case WEEK_OF_YEAR:            case WEEK_OF_MONTH:            case DAY_OF_WEEK_IN_MONTH:                delta *= 7 * 24 * 60 * 60 * 1000; // 7 days                break;            case AM_PM:                delta *= 12 * 60 * 60 * 1000; // 12 hrs                break;            case DATE: // synonym of DAY_OF_MONTH            case DAY_OF_YEAR:            case DAY_OF_WEEK:                delta *= 24 * 60 * 60 * 1000; // 1 day                break;            case HOUR_OF_DAY:            case HOUR:                delta *= 60 * 60 * 1000; // 1 hour                adjustDST = false;                break;            case MINUTE:                delta *= 60 * 1000; // 1 minute                adjustDST = false;                break;            case SECOND:                delta *= 1000; // 1 second                adjustDST = false;                break;            case MILLISECOND:                adjustDST = false;                break;            case ZONE_OFFSET:            case DST_OFFSET:            default:                throw new IllegalArgumentException();            }            // Save the current DST state.            long dst = 0;            if (adjustDST) {		dst = internalGet(DST_OFFSET);	    }            setTimeInMillis(time + delta); // Automatically computes fields if necessary            if (adjustDST) {                // Now do the DST adjustment alluded to above.                // Only call setTimeInMillis if necessary, because it's an expensive call.                dst -= internalGet(DST_OFFSET);                if (dst != 0) {		    setTimeInMillis(time + dst);		}            }        }    }    /**     * Adds or subtracts (up/down) a single unit of time on the given time     * field without changing larger fields.      * <p>     * <em>Example</em>: Consider a <code>GregorianCalendar</code>     * originally set to December 31, 1999. Calling <code>roll(Calendar.MONTH, true)</code>     * sets the calendar to January 31, 1999.  The <code>Year</code> field is unchanged     * because it is a larger field than <code>MONTH</code>.</p>     * @param up indicates if the value of the specified time field is to be     * rolled up or rolled down. Use true if rolling up, false otherwise.     * @exception IllegalArgumentException if an unknown field value is given.     * @see GregorianCalendar#add     * @see GregorianCalendar#set     */    public void roll(int field, boolean up) {        roll(field, up ? +1 : -1);    }    /**     * Add to field a signed amount without changing larger fields.     * A negative roll amount means to subtract from field without changing      * larger fields.     * <p>     * <em>Example</em>: Consider a <code>GregorianCalendar</code>     * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH,     * 8)</code> sets the calendar to April 30, <strong>1999</strong>. Using a     * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> field cannot     * be 31 in the month April. <code>DAY_OF_MONTH</code> is set to the closest possible     * value, 30. The <code>YEAR</code> field maintains the value of 1999 because it     * is a larger field than <code>MONTH</code>.     * <p>     * <em>Example</em>: Consider a <code>GregorianCalendar</code>     * originally set to Sunday June 6, 1999. Calling     * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to     * Tuesday June 1, 1999, whereas calling     * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to     * Sunday May 30, 1999. This is because the roll rule imposes an     * additional constraint: The <code>MONTH</code> must not change when the     * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1,     * the resultant date must be between Tuesday June 1 and Saturday June     * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant     * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the     * closest possible value to Sunday (where Sunday is the first day of the     * week).</p>     * @param field the time field.     * @param amount the signed amount to add to <code>field</code>.     * @since 1.2     * @see GregorianCalendar#add     * @see GregorianCalendar#set     */    public void roll(int field, int amount) {        if (amount == 0) {	    return; // Nothing to do	}        int min = 0, max = 0, gap;        if (field >= 0 && field < FIELD_COUNT) {            complete();            min = getMinimum(field);            max = getMaximum(field);        }        switch (field) {        case ERA:        case YEAR:        case AM_PM:        case MINUTE:        case SECOND:        case MILLISECOND:            // These fields are handled simply, since they have fixed minima            // and maxima.  The field DAY_OF_MONTH is almost as simple.  Other            // fields are complicated, since the range within they must roll            // varies depending on the date.            break;        case HOUR:        case HOUR_OF_DAY:            // Rolling the hour is difficult on the ONSET and CEASE days of            // daylight savings.  For example, if the change occurs at            // 2 AM, we have the following progression:            // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst            // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std            // To get around this problem we don't use fields; we manipulate            // the time in millis directly.            {                // Assume min == 0 in calculations below                Date start = getTime();                int oldHour = internalGet(field);                int newHour = (oldHour + amount) % (max + 1);                if (newHour < 0) {                    newHour += max + 1;                }                setTime(new Date(start.getTime() + ONE_HOUR * (newHour - oldHour)));                return;            }        case MONTH:            // Rolling the month involves both pinning the final value to [0, 11]            // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the            // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.            // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.            {                int mon = (internalGet(MONTH) + amount) % 12;                if (mon < 0) {		    mon += 12;		}                set(MONTH, mon);                                // Keep the day of month in range.  We don't want to spill over                // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->                // mar3.                // NOTE: We could optimize this later by checking for dom <= 28                // first.  Do this if there appears to be a need. [LIU]                int monthLen = monthLength(mon);                int dom = internalGet(DAY_OF_MONTH);                if (dom > monthLen) {		    set(DAY_OF_MONTH, monthLen);		}                return;            }        case WEEK_OF_YEAR:            {                // Unlike WEEK_OF_MONTH, WEEK_OF_YEAR never shifts the day of the                // week.  Also, rolling the week of the year can have seemingly                // strange effects simply because the year of the week of year                // may be different from the calendar year.  For example, the                // date Dec 28, 1997 is the first day of week 1 of 1998 (if                // weeks start on Sunday and the minimal days in first week is                // <= 3).                int woy = internalGet(WEEK_OF_YEAR);                // Get the ISO year, which matches the week of year.  This                // may be one year before or after the calendar year.                int isoYear = internalGet(YEAR);                int isoDoy = internalGet(DAY_OF_YEAR);                if (internalGet(MONTH) == Calendar.JANUARY) {                    if (woy >= 52) {                        --isoYear;                        isoDoy += yearLength(isoYear);                    }                } else {                    if (woy == 1) {                        isoDoy -= yearLength(isoYear);                        ++isoYear;                    }                }                woy += amount;                // Do fast checks to avoid unnecessary computation:                if (woy < 1 || woy > 52) {                    // Determine the last week of the ISO year.		    // First, we calculate the relative fractional days of the		    // last week of the year. (This doesn't include days in 		    // the year before or after the calendar year.)                    int lastDoy = yearLength(isoYear);                    int normalizedDayOfWeek = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();                    if (normalizedDayOfWeek < 0) {                        normalizedDayOfWeek += 7;                    }                    int lastRelDow = (lastDoy - isoDoy + normalizedDayOfWeek) % 7;                    if (lastRelDow < 0) {                        lastRelDow += 7;                    }		    // Next, calculate the minimal last week of year.		    // Now this value is just the total number of weeks in the		    // year all of which have 7 days a week. Need to check the		    // first and the last week of the year, which would have 		    // days fewer than 7.                    int lastWoy;                    lastDoy -= (lastRelDow+1);                    lastWoy = lastDoy / 7;		    // If the relative fraction of the first week of the year		    // is more than MinimalDaysInFirstWeek, add 1 to the last		    // week // of the year.                    if ((lastDoy - (lastWoy*7)) >= getMinimalDaysInFirstWeek()) {                        lastWoy++;                    }		    // If the relative fraction of the last week of the year 		    // is more than MinimalDaysInFirstWeek, add 1 to the last		    // week of the year.                    if ((6 - lastRelDow) < getMinimalDaysInFirstWeek()) {                        lastWoy++;                    }                    woy = ((woy + lastWoy - 1) % lastWoy) + 1;                }                set(WEEK_OF_YEAR, woy);                set(YEAR, isoYear);                return;            }        case WEEK_OF_MONTH:            {                // This is tricky, because during the roll we may have to shift                // to a different day of the week.  For example:                //    s  m  t  w  r  f  s                //          1  2  3  4  5                //    6  7  8  9 10 11 12                // When rolling from the 6th or 7th back one week, we go to the                // 1st (assuming that the first partial week counts).  The same                // thing happens at the end of the month.                // The other tricky thing is that we have to figure out whether                // the first partial week actually counts or not, based on the                // minimal first days in the week.  And we have to use the                // correct first day of the week to delineate the week                // boundaries.                // Here's our algorithm.  First, we find the real boundaries of                // the month.  Then we discard the first partial week if it                // doesn't count in this locale.  Then we fill in the ends with                // phantom days, so that the first partial week and the last                // partial week are full weeks.  We then have a nice square                // block of weeks.  We do the usual rolling within this block,                // as is done elsewhere in this method.  If we wind up on one of                // the phantom days that we added, we recognize this and pin to                // the first or the last day of the month.  Easy, eh?                // Normalize the DAY_OF_WEEK so that 0 is the first day of the week                // in this locale.  We have dow in 0..6.                int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();                if (dow < 0) {		    dow += 7;		}                // Find the day of the week (normalized for locale) for the first                // of the month.                int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7;                if (fdm < 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -