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 + -
显示快捷键?