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