📄 gregoriancalendar.java
字号:
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: complete(); fields[ZONE_OFFSET] += amount; time -= amount; break; case DST_OFFSET: complete(); fields[DST_OFFSET] += amount; isTimeSet = false; break; default: throw new IllegalArgumentException ("Unknown Calendar field: " + 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. * * <strong>Note:</strong> 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. */ public void roll(int field, boolean up) { roll(field, up ? 1 : -1); } 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. * * <strong>Note:</strong> 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. */ 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); } private static final int[] minimums = { BC, 1, 0, 0, 1, 1, 1, SUNDAY, 1, AM, 1, 0, 1, 1, 1, -(12*60*60*1000), 0 }; 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 the time field. One of the time field constants. * @return the smallest value. */ public int getMinimum(int field) { return minimums[field]; } /** * Gets the biggest value that is allowed for the specified field. * @param field the time 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. * @param field the time field. One of the time field constants. * @return the greatest minimum value. */ 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. For example this is 28 for DAY_OF_MONTH. * @param field the time field. One of the time field constants. * @return the least maximum value. * @since jdk1.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 <code>complete()</code> if not enough fields are set. This * can have ugly side effects. * @param field the time field. One of the time field constants. * @return the actual minimum value. * @since jdk1.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 <code>complete()</code> if not enough fields are set. This * can have ugly side effects. * @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); if (minimalDays - (7 + firstWeekday - getFirstDayOfWeek()) % 7 < 1) return week + 1; } 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]; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -