按時間間隔生成cron表達式


cron表達式是使用任務調度經常使用的表達式了。對於通常的簡單任務,我們只需要一條cron表達式就能滿足。但是有的時候任務也可以很復雜。
最近我遇到了一個問題,一條任務在開始的時候要觸發A方法,在結束的時候需要觸發B方法。所以每次我添加觸發器的時候都需要兩個cron表達式,兩個表達式需要間隔一定的時間。聽起來特別復雜,但是實際上我只需要實現每天、每周、每月的時間就可以了。
選擇每天時,持續時間不超過一天。
選擇每周時,持續時間不超過一周。
選擇每月時,持續時間不超過30天。

public class cronExpressionAddDuration {
	public static void main(String[] args) {
		/* {"cron":"0 0 0 31 * ?","duration":2678400}*/
		/* {"cron":"0 20 0 ? * 7","duration":604740}*/
		/* {"cron":"0 20 0 * * ?","duration":86340}*/
		/* {"cron":"0 59 23 L * ?","duration":2678340} */
		String cron="cron\":\"0 59 23 L * ?";
		int duration=2678340;
		String newCron=cronExpressionPlusDuration(cron,duration);
		System.out.println(newCron);
	}
	  /**
     * <p>對cron表達式進行修改,根據傳入的時間生成一個新的cron表達式</>
     * 兩個表達式之間的間隔為duration
     *
     * @param cron
     * @param duration 單位為秒
     * @return
     */
    private static String cronExpressionPlusDuration(String cron, int duration) {
       
        String[] cronArray = cron.split(" ");
        int days = duration / 86400;
        int hours = (duration % (86400)) / 3600;
        int minutes = ((duration % (86400)) % 3600) / 60;
        cronArray[2] = String.valueOf(Integer.valueOf(cronArray[2]) + hours);
        cronArray[1] = String.valueOf(Integer.valueOf(cronArray[1]) + minutes);
        /* 對小時和分鍾進行合法性校驗*/
        if (Integer.valueOf(cronArray[1]) >= 60 || Integer.valueOf(cronArray[2]) >= 24) {
            int extraMinutes = Integer.valueOf(cronArray[1]) % 60;
            int extraHours = (Integer.valueOf(cronArray[2])+ Integer.valueOf(cronArray[1]) / 60)%24;
            cronArray[2] = String.valueOf(extraHours);
            cronArray[1] = String.valueOf(extraMinutes);
        }
        /* 持續時間一天以內*/
        if (duration < 86400 && "*".equals(cronArray[3]) && "*".equals(cronArray[4]) && "?".equals(cronArray[5])) {

        } else if (duration > 86400 && duration < 86400 * 7) {
            cronArray[5] = String.valueOf((Integer.valueOf(cronArray[5]) + days) % 7 + 1);
        } else if (duration > 86400 * 7 && duration < 86400 * 32) {
            if("L".equals(cronArray[3])){
                cronArray[3]=String.valueOf(days);
            }else {
                cronArray[3] = String.valueOf(((Integer.valueOf(cronArray[3]) + days) % 31) + 1);
            }
        }
        String result = "";
        for (String s : cronArray) {
            result += s + " ";
        }
        return result;
    }
}

代碼寫完了,但是這個方法有個缺陷。

  1. 如果期望添加一個暫停方式是每月且持續時間超過28天的表達式,那么在二月份該表達式不會生效。
  2. 如果期望添加一個暫停方式是每月的表達式,例如每月最后一天00:00持續時間5天。
    假如我在3號添加了這條規則,如果此時該任務還有一個規則是5號不應該恢復,理論上我們不希望再次觸發。但實際上此時這條規則會在5號觸發。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM