⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alarmentry.java

📁 一个Java的类似cron的日程安排提醒程序。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
    }
    
    /**
     * daysInMonth can't use simple offsets like the other fields, because the
     * number of days varies per month (think of an alarm that executes on every
     * 31st).  Instead we advance month and dayInMonth together until we're on a
     * matching value pair.
     */
    void updateDayOfMonthAndMonth( Calendar alarm )
    {
        int currentMonth = alarm.get( Calendar.MONTH );
        int currentDayOfMonth = alarm.get( Calendar.DAY_OF_MONTH );
        int offset = 0;
        
        // loop until we have a valid day AND month (if current is invalid)
        while( !isIn(currentMonth, months) || !isIn(currentDayOfMonth, daysOfMonth) )
        {
            // if current month is invalid, advance to 1st day of next valid month
            if( !isIn(currentMonth, months) )
            {
                offset = getOffsetToNextOrEqual( currentMonth, minMonth, maxMonth, months );
                alarm.add( Calendar.MONTH, offset );
                alarm.set( Calendar.DAY_OF_MONTH, 1 );
                currentDayOfMonth = 1;
            }
            
            // advance to the next valid day of month, if necessary
            if( !isIn(currentDayOfMonth, daysOfMonth) )
            {
                int maxDayOfMonth = alarm.getActualMaximum( Calendar.DAY_OF_MONTH );
                offset = getOffsetToNextOrEqual( currentDayOfMonth, minDayOfMonth, maxDayOfMonth, daysOfMonth );
                alarm.add( Calendar.DAY_OF_MONTH, offset );
            }
            
            currentMonth = alarm.get( Calendar.MONTH );
            currentDayOfMonth = alarm.get( Calendar.DAY_OF_MONTH );
        }
    }
    
    
    void updateDayOfWeekAndMonth( Calendar alarm )
    {
        int currentMonth = alarm.get( Calendar.MONTH );
        int currentDayOfWeek = alarm.get( Calendar.DAY_OF_WEEK );
        int offset = 0;
        
        // loop until we have a valid day AND month (if current is invalid)
        while( !isIn(currentMonth, months) || !isIn(currentDayOfWeek, daysOfWeek) )
        {
            // if current month is invalid, advance to 1st day of next valid month
            if( !isIn(currentMonth, months) )
            {
                offset = getOffsetToNextOrEqual( currentMonth, minMonth, maxMonth, months );
                alarm.add( Calendar.MONTH, offset );
                alarm.set( Calendar.DAY_OF_MONTH, 1 );
                currentDayOfWeek = alarm.get( Calendar.DAY_OF_WEEK );
            }
            
            // advance to the next valid day of week, if necessary
            if( !isIn(currentDayOfWeek, daysOfWeek) )
            {
                offset = getOffsetToNextOrEqual( currentDayOfWeek, minDayOfWeek, maxDayOfWeek, daysOfWeek );
                alarm.add( Calendar.DAY_OF_YEAR, offset );
            }
            
            currentDayOfWeek = alarm.get( Calendar.DAY_OF_WEEK );
            currentMonth = alarm.get( Calendar.MONTH );
        }
    }
    
    
    
    // ----------------------------------------------------------------------
    //                      General utility methods
    // ----------------------------------------------------------------------
    
    /**
     * if values = {-1}
     *   offset is 1 (because next value definitely matches)
     * if current < last(values)
     *   offset is diff to next valid value
     * if current >= last(values)
     *   offset is diff to values[0], wrapping from max to min
     */
    static int getOffsetToNext( int current, int min, int max, int[] values )
    {
        int offset = 0;
        
        // find the distance to the closest valid value > current (wrapping if neccessary)
        
        // {-1} means *  -- offset is 1 because current++ is valid value
        if (values[0] == -1 )
        {
            offset = 1;
        }
        else
        {
            // need to wrap
            if( current >= last(values) )
            {
                int next = values[0];
                offset = (max-current+1) + (next-min);
            }
            else // current < max(values) -- find next valid value after current
            {
                findvalue:
                for( int i=0; i<values.length; i++ )
                {
                    if( current < values[i] )
                    {
                        offset = values[i] - current;
                        break findvalue;
                    }
                }
            } // end current < max(values)
        }
        
        return offset;
    }
    
    /**
     * if values = {-1} or current is valid
     *   offset is 0.
     * if current < last(values)
     *   offset is diff to next valid value
     * if current >= last(values)
     *   offset is diff to values[0], wrapping from max to min
     */
    static int getOffsetToNextOrEqual( int current, int min, int max, int[] values )
    {
        int offset = 0;
        int[] safeValues = null;
        
        // find the distance to the closest valid value >= current (wrapping if necessary)
        
        // {-1} means *  -- offset is 0 if current is valid value
        if (values[0] == -1 || isIn(current, values) )
        {
            offset = 0;
        }
        else
        {
            safeValues = discardValuesOverMax( values, max );
            
            // need to wrap
            if( current > last(safeValues) )
            {
                int next = safeValues[0];
                offset = (max-current+1) + (next-min);
            }
            else // current <= max(values) -- find next valid value
            {
                findvalue:
                for( int i=0; i<values.length; i++ )
                {
                    if( current < safeValues[i] )
                    {
                        offset = safeValues[i] - current;
                        break findvalue;
                    }
                }
            } // end current <= max(values)
        }
        
        return offset;
    }
    
    /**
     * handles -1 in values as * and returns true
     * otherwise returns true iff given value is in the array
     */
    static boolean isIn( int find, int[] values )
    {
        if( values[0] == -1 )
        {
            return true;
        }
        else
        {
            for( int i=0; i<values.length; i++ )
            {
                if( find == values[i] )
                    return true;
            }
            return false;
        }
    }
    
    /**
     * @return the last int in the array
     */
    static int last( int[] intArray )
    {
        return intArray[ intArray.length - 1 ];
    }
    
    /**
     * Assumes inputted values are not null, have at least one value, and are in
     * ascending order.
     * @return  copy of values without any trailing values that exceed the max
     */
    static int[] discardValuesOverMax( int[] values, int max )
    {
        int[] safeValues = null;
        for( int i=0; i<values.length; i++ )
        {
            if( values[i] > max )
            {
                safeValues = new int[i];
                System.arraycopy( values, 0, safeValues, 0, i );
                return safeValues;
            }
        }
        return values;
    }

    
    private static String arrToString( int[] intArray )
    {
        if( intArray == null )
            return "null";
        if( intArray.length == 0 )
            return "{}";
        
        String s = "{";
        for( int i=0; i<intArray.length-1; i++ )
        {
            s += intArray[i] + ", ";
        }
        s += intArray[intArray.length-1] + "}";
        
        return s;
    }
    
    // ----------------------------------------------------------------------
    //                      Comparable interface
    // ----------------------------------------------------------------------
    
    /**
     * Compares this AlarmEntry with the specified AlarmEntry for order.
     * One twist -- if the alarmTime matches, this alarm will STILL place
     * itself before the other based on the lastUpdateTime.  If the other 
     * alarm has been rung more recently, this one should get priority.
     *
     * @param obj the AlarmEntry with which to compare.
     * @return a negative integer, zero, or a positive integer as this
     * AlarmEntry is less than, equal to, or greater than the given
     * AlarmEntry.
     * @exception ClassCastException if the specified Object's type
     * prevents it from being compared to this AlarmEntry.
     */
    public int compareTo(Object obj) {
        AlarmEntry other = (AlarmEntry)obj;
        if (alarmTime < other.alarmTime)
            return -1;
        else if (alarmTime > other.alarmTime)
            return 1;
        else // alarmTime == other.alarmTime
        {
            if( lastUpdateTime < other.lastUpdateTime )
                return -1;
            else if( lastUpdateTime > other.lastUpdateTime)
                return 1;
            else
                return 0;    
        }
    }
    
    
    /**
     * Indicates whether some other AlarmEntry is "equal to" this one.
     * This is where the name is important, since two alarms can have the
     * exact same schedule.
     *
     * @param obj the AlarmEntry with which to compare.
     * @return <code>true if this AlarmEntry has the same name,
     * <code>alarmTime</code> AND the same schedule as the
     * obj argument;
     * <code>false</code> otherwise.
     */
    public boolean equals(Object obj) {
        AlarmEntry entry = null;
        
        if( obj == null || !(obj instanceof AlarmEntry) )
            return false;
        
        entry = (AlarmEntry)obj;
        return (   name.equals(entry.name)
                && alarmTime == entry.alarmTime
                && isRelative == entry.isRelative
                && isRepeating == entry.isRepeating
                && Arrays.equals(minutes, entry.minutes)
                && Arrays.equals(hours, entry.hours)
                && Arrays.equals(daysOfMonth, entry.daysOfMonth)
                && Arrays.equals(months, entry.months)
                && Arrays.equals(daysOfWeek, entry.daysOfWeek) );
    }
    
    
    
    /**
     * @return a string representation of this alarm.
     */
    public String toString() {
        if (year != -1) {
            return "Alarm ("+name+") at " + new Date(alarmTime);
        }
        StringBuffer sb = new StringBuffer("Alarm ("+name+") params");
        sb.append(" minute="); sb.append( arrToString(minutes) );
        sb.append(" hour="); sb.append( arrToString(hours) );
        sb.append(" dayOfMonth="); sb.append( arrToString(daysOfMonth) );
        sb.append(" month="); sb.append( arrToString(months) );
        sb.append(" dayOfWeek="); sb.append( arrToString(daysOfWeek) );
        sb.append(" (next alarm date=" + new Date(alarmTime) + ")");
        return sb.toString();
    }
    
    
    /**
     * some unit testing...
     */
    public static void main( String[] args ) {
        
        System.out.println( "GETTING OFFSETS" );
        
        System.out.println( "getOffsetToNext(3, 0, 11, new int[]{3,5,7,9}) = " +
                getOffsetToNext(3, 0, 11, new int[]{3,5,7,9}) );
        System.out.println( "getOffsetToNextOrEqual(3, 0, 11, new int[]{3,5,7,9}) = " +
                getOffsetToNextOrEqual(3, 0, 11, new int[]{3,5,7,9}) );
        
        System.out.println();
        System.out.println( "getOffsetToNext(9, 0, 11, new int[]{3,5,7,9}) = " +
                getOffsetToNext(9, 0, 11, new int[]{3,5,7,9}) );
        System.out.println( "getOffsetToNextOrEqual(9, 0, 11, new int[]{3,5,7,9}) = " +
                getOffsetToNextOrEqual(9, 0, 11, new int[]{3,5,7,9}) );
        
        System.out.println();
        System.out.println( "getOffsetToNext(0, 0, 11, new int[]{0}) = " +
                getOffsetToNext(0, 0, 11, new int[]{0}) );
        System.out.println( "getOffsetToNextOrEqual(0, 0, 11, new int[]{0}) = " +
                getOffsetToNextOrEqual(0, 0, 11, new int[]{0}) );
        
        System.out.println();
        System.out.println( "getOffsetToNext(5, 0, 11, new int[]{5}) = " +
                getOffsetToNext(5, 0, 11, new int[]{5}) );
        System.out.println( "getOffsetToNextOrEqual(5, 0, 11, new int[]{5}) = " +
                getOffsetToNextOrEqual(5, 0, 11, new int[]{5}) );
        
        System.out.println();
        System.out.println( "getOffsetToNext(0, 0, 11, new int[]{-1}) = " +
                getOffsetToNext(0, 0, 11, new int[]{-1}) );
        System.out.println( "getOffsetToNextOrEqual(0, 0, 11, new int[]{-1}) = " +
                getOffsetToNextOrEqual(0, 0, 11, new int[]{-1}) );
        
        System.out.println();
        
        System.out.println();
        System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 4)) = " + 
                arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 4)) );
        System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 6)) = " + 
                arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 6)) );
        System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 0)) = " + 
                arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 0)) );
        System.out.println( "discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 7)) = " + 
                arrToString(discardValuesOverMax(new int[]{0,1,2,3,4,5,6}, 7)) );
    }
}









⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -