gregoriancalendar.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 989 行 · 第 1/3 页

JAVA
989
字号
				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 + =
减小字号Ctrl + -
显示快捷键?