schedule.java
来自「数据仓库展示程序」· Java 代码 · 共 834 行 · 第 1/3 页
JAVA
834 行
int weeksOfMonthBitmap;
MonthlyByWeekDateSchedule(
Calendar begin, int period, int daysOfWeekBitmap,
int weeksOfMonthBitmap) {
this.period = period;
ScheduleUtil.assertTrue(period > 0, "period must be positive");
this.beginMonth = begin == null ? 0 : monthOrdinal(begin);
this.daysOfWeekBitmap = daysOfWeekBitmap;
ScheduleUtil.assertTrue(
(daysOfWeekBitmap & Schedule.allDaysOfWeekBitmap) != 0,
"weekly schedule must have at least one day set");
ScheduleUtil.assertTrue(
(daysOfWeekBitmap & Schedule.allDaysOfWeekBitmap) ==
daysOfWeekBitmap,
"weekly schedule has bad bits set: " + daysOfWeekBitmap);
this.weeksOfMonthBitmap = weeksOfMonthBitmap;
ScheduleUtil.assertTrue(
(weeksOfMonthBitmap & Schedule.allWeeksOfMonthBitmap) != 0,
"weeks of month schedule must have at least one week set");
ScheduleUtil.assertTrue(
(weeksOfMonthBitmap & Schedule.allWeeksOfMonthBitmap) ==
weeksOfMonthBitmap,
"week of month schedule has bad bits set: " +
weeksOfMonthBitmap);
}
public Calendar nextOccurrence(Calendar earliest, boolean strict) {
earliest = (Calendar) earliest.clone();
if (strict) {
earliest.add(Calendar.DATE, 1);
}
// should be enough... worst case is '5th Monday of every 3rd month'
int i = 365 + period;
while (i-- > 0) {
int month = monthOrdinal(earliest);
if ((month - beginMonth) % period != 0) {
// not this month! move to first of next month
earliest.set(Calendar.DAY_OF_MONTH, 1);
earliest.add(Calendar.MONTH, 1);
continue;
}
// is it one of the days we're interested in?
int dayOfWeek = earliest.get(Calendar.DAY_OF_WEEK);
if ((daysOfWeekBitmap & (1 << dayOfWeek)) != 0) {
// is it the Yth occurrence of day X?
int dayOfMonth = earliest.get(Calendar.DAY_OF_MONTH);
int weekOfMonth = (dayOfMonth + 6) / 7; // 1-based
if ((weeksOfMonthBitmap & (1 << weekOfMonth)) != 0) {
return earliest;
}
// is it the last occurrence of day X?
if ((weeksOfMonthBitmap & (1 << Schedule.LAST_WEEK_OF_MONTH))
!= 0) {
// we're in the last week of the month iff a week later is
// in the first week of the next month
earliest.add(Calendar.WEEK_OF_MONTH, 1);
boolean isLast = earliest.get(Calendar.DAY_OF_MONTH) <= 7;
earliest.add(Calendar.WEEK_OF_MONTH, -1);
if (isLast) {
return earliest;
}
}
}
earliest.add(Calendar.DATE, 1);
}
throw ScheduleUtil.newInternal(
"monthy-by-week date schedule is cyclic");
}
private static int monthOrdinal(Calendar earliest) {
return earliest.get(Calendar.YEAR) * 12 +
earliest.get(Calendar.MONTH);
}
}
/**
* Utility functions for {@link Schedule} and supporting classes.
*/
class ScheduleUtil {
static final Calendar epochDay = ScheduleUtil.createCalendar(new Date(0));
static final Calendar midnightTime = ScheduleUtil.createTimeCalendar(0,0,0);
public static void assertTrue(boolean b) {
if (!b) {
throw new Error("assertion failed");
}
}
public static void assertTrue(boolean b, String s) {
if (!b) {
throw new Error("assertion failed: " + s);
}
}
public static Error newInternal() {
return new Error("internal error");
}
public static Error newInternal(Throwable e, String s) {
return new Error("internal error '" + e + "': " + s);
}
public static Error newInternal(String s) {
return new Error("internal error: " + s);
}
public static boolean lessThan(Time t1, Time t2, boolean strict) {
if (strict) {
return t1.getTime() < t2.getTime();
} else {
return t1.getTime() <= t2.getTime();
}
}
public static boolean lessThan(Date d1, Date d2, boolean strict) {
if (strict) {
return d1.getTime() < d2.getTime();
} else {
return d1.getTime() <= d2.getTime();
}
}
public static boolean is0000(Calendar calendar) {
return calendar.get(Calendar.HOUR_OF_DAY) == 0 &&
calendar.get(Calendar.MINUTE) == 0 &&
calendar.get(Calendar.SECOND) == 0 &&
calendar.get(Calendar.MILLISECOND) == 0;
}
public static boolean isTime(Calendar calendar) {
return calendar.get(Calendar.YEAR) ==
ScheduleUtil.epochDay.get(Calendar.YEAR) &&
calendar.get(Calendar.DAY_OF_YEAR) ==
ScheduleUtil.epochDay.get(Calendar.DAY_OF_YEAR);
}
/**
* Returns a calendar rounded down to the previous midnight.
*/
public static Calendar floor(Calendar calendar) {
if (calendar == null) {
return null;
}
calendar = (Calendar) calendar.clone();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
/**
* Returns a calendar rounded up to the next midnight, unless it is already
* midnight.
*/
public static Calendar ceiling(Calendar calendar) {
if (calendar == null) {
return null;
}
if (is0000(calendar)) {
return calendar;
}
calendar = (Calendar) calendar.clone();
calendar.add(Calendar.DATE, 1);
return calendar;
}
/**
* Extracts the time part of a date. Given a null date, returns null.
*/
public static Calendar getTime(Calendar calendar) {
if (calendar == null) {
return null;
}
return createTimeCalendar(
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND));
}
/**
* Creates a calendar in UTC, and initializes it to <code>date</code>.
*
* @pre date != null
* @post return != null
*/
public static Calendar createCalendar(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(Schedule.utcTimeZone);
calendar.setTime(date);
return calendar;
}
/**
* Creates a calendar in UTC, and initializes it to a given year, month,
* day, hour, minute, second. <b>NOTE: month is 1-based</b>
*/
public static Calendar createCalendar(
int year, int month, int day, int hour, int minute, int second) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(Schedule.utcTimeZone);
calendar.toString(); // calls complete()
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month - 1); // CONVERT TO 0-BASED!!
calendar.set(Calendar.DAY_OF_MONTH, day);
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
/**
* Creates a calendar from a time. Milliseconds are ignored.
*
* @pre time != null
* @post return != null
*/
public static Calendar createTimeCalendar(Time time) {
Calendar calendar = (Calendar) ScheduleUtil.epochDay.clone();
calendar.setTimeZone(Schedule.utcTimeZone);
calendar.setTime(time);
return createTimeCalendar(
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND));
}
/**
* Creates a calendar and sets it to a given hours, minutes, seconds.
*/
public static Calendar createTimeCalendar(
int hours, int minutes, int seconds) {
Calendar calendar = (Calendar) ScheduleUtil.epochDay.clone();
calendar.set(Calendar.HOUR_OF_DAY, hours);
calendar.set(Calendar.MINUTE, minutes);
calendar.set(Calendar.SECOND, seconds);
calendar.set(Calendar.MILLISECOND, 0);
return calendar;
}
/**
* Creates a calendar and sets it to a given year, month, date.
*/
public static Calendar createDateCalendar(
int year, int month, int dayOfMonth) {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(Schedule.utcTimeZone);
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
return calendar;
}
/**
* Creates a {@link java.sql.Time}
*/
public static Time createTime(int hour, int minutes, int second) {
return new Time(
createTimeCalendar(hour, minutes, second).getTime().getTime());
}
/**
* Returns the julian day number of a given date. (Is there a better way
* to do this?)
*/
public static int julianDay(Calendar calendar) {
int year = calendar.get(Calendar.YEAR),
day = calendar.get(Calendar.DAY_OF_YEAR),
leapDays = (year / 4) - (year / 100) + (year / 400);
return year * 365 + leapDays + day;
}
/**
* Returns the offset from UTC in milliseconds in this timezone on a given
* date.
*/
public static int timezoneOffset(TimeZone tz, Calendar calendar) {
return tz.getOffset(
calendar.get(Calendar.ERA),
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
calendar.get(Calendar.DAY_OF_WEEK),
(1000 *
(60 *
(60 * calendar.get(Calendar.HOUR_OF_DAY) +
calendar.get(Calendar.MINUTE)) +
calendar.get(Calendar.SECOND)) +
calendar.get(Calendar.MILLISECOND)));
}
}
// End Schedule.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?