2010-04-26 2 views
6

Java에서 Cron Expression으로 "Last Fired Time"을 찾는 방법이 있습니까?Java에서 Cron Expression을 사용하여 마지막 실행 시간 찾기

예. 예 = 2010 년 4 월 25 일 오후 10시, cron 표현식 "0 15 10? * *"(석영)이 나를 반환해야 함 2010 년 4 월 25 일 오전 10시 15 분

참고 : 1) 나에게 올바른 "Last Fired Time"을 가져올 수 있다면 표준 cron 표현식 (Unix 및 Quartz와 같은) 또는 덜 인기있는 표현 2) 또한 트리거가 실행되지 않았으므로 문자 그대로 "Last Fire Time"이 아니지만 논리적으로는 마지막으로 해고 될 때를 말해주는 방법이되어야합니다.

답변

2

먼저이 기능을 지원하는 기존 라이브러리를 알지 못합니다. Quartz 일지 모르지만 표준 자바 클래스 라이브러리는 그렇지 않다.

두 번째로 엄밀히 말하면 은 원래 묻는 은 불가능합니다. 라이브러리가 알 수있는 가장 좋은 점은 cron 표현식 또는 이어야한다는 것입니다. cron 표현식이 실제로 실행 된 마지막 시간을 (이론적으로) 알려주는 유일한 방법은 스케줄러 인스턴스 자체입니다.

+0

안녕하세요. Stephen, 보내 주신 의견에 감사드립니다. 내 문제를 해결하기 위해 내 질문에 메모에 조금 더 많은 정보를 추가했습니다. –

1

Quartz는 cron 표현식에 대한 라이브러리 지원을 갖고있는 것으로 보입니다.

the Javadoc for the CronExpression class을 참조하십시오. 여기에는 getTimeBefore이라는 방법이 있습니다. 즉,

CronExpression cron = new CronExpression("0 15 10 ? * *"); 
Date today = new Date(); 
Date previousExecution = cron.getTimeBefore(today); 

이것은 작동하는지 여부에 따라 Quartz 버전에 따라 달라질 수 있습니다.

최신 소스 (작성 당시 버전 2.1.0)를 보면이 메소드는 구현되지 않았으며 항상 null을 반환합니다.

2

Quartz에서 발견 한 해결책은 방아쇠를 한 시간 간격으로 되돌려 놓고 다음 발사 시간을 계산하는 것입니다. 모든 트리거를 반복함으로써 트리거가 과거에 발사 한 가장 최근의 시간을 결정할 수 있습니다.


각 발사 사이의 간격 계산 :

Date nextFireTime = trigger.getNextFireTime(); 
Date subsequentFireTime = trigger.getFireTimeAfter(nextFireTime); 
long interval = subsequentFireTime.getTime() - nextFireTime.getTime(); 

과거에 간격 때까지 한 번에 다음 발사 시간을 찾기 :

Date previousPeriodTime = new Date(System.currentTimeMillis() - interval); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 

난 당신이 사용하는 경우 것으로 나타났습니다 CronTrigger 이렇게하면 과거에 화재 시간을 묻지 않게됩니다. 트리거의 모든 통해

Date originalStartTime = trigger.getStartTime(); // save the start time 
Date previousPeriodTime = new Date(originalStartTime.getTime() - interval); 
trigger.setStartTime(previousPeriodTime); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 
trigger.setStartTime(originalStartTime); // reset the start time to be nice 

반복 처리를 과거에 가장 최근 인 하나 찾을 :이 문제를 해결하기 위해 나는 위의 코드가 될 수 있도록, 시작 시간을 변경 나 '

for (String groupName : scheduler.getTriggerGroupNames()) { 
    for (String triggerName : scheduler.getTriggerNames(groupName)) { 
     Trigger trigger = scheduler.getTrigger(triggerName, groupName); 
     // code as detailed above... 
     interval = ... 
     previousFireTime = ... 
    } 
} 

을 이것을 헬퍼 메소드 나 클래스로 리팩터링하기 위해 독자에게 연습 문제로 남겨 둡니다. 실제로 서브 클래 싱 된 위임 트리거에서 위의 알고리즘을 사용하여 이전 발사 시간순으로 정렬 된 집합에 배치합니다.https://github.com/devbhuwan/cron-micro-utils

+2

후속 화재의 차이는 항상 동일하지 않습니다. – Ahamed

0
public class CronMircoUtils { 

    /** 
    * Use this method to calculate previous valid date for cron 
    * @param ce CronExpression object with cron expression 
    * @param date Date for find previous valid date 
    * @return 
    */ 
    public static Date getPreviousValidDate(CronExpression ce, Date date) { 
     try { 
      Date nextValidTime = ce.getNextValidTimeAfter(date); 
      Date subsequentNextValidTime = ce.getNextValidTimeAfter(nextValidTime); 
      long interval = subsequentNextValidTime.getTime() - nextValidTime.getTime(); 
      return new Date(nextValidTime.getTime() - interval); 
     } catch (Exception e) { 
      throw new IllegalArgumentException("Unsupported cron or date", e); 
     } 
    } 
} 

소스 코드 구문 분석, 검증, 당신이 필요로하는 작업을 지원 크론를 마이그레이션 할 수있는 오픈 소스 자바 라이브러리입니다. 는 단순히 주어진 시간 전에 크론에서 이전 날짜를 얻으려면 :

//Get date for last execution 
DateTime now = DateTime.now(); 
ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("* * * * * * *")); 
DateTime lastExecution = executionTime.lastExecution(now)); 

곰을 현재 상태로는 약간의 버그가 더 복잡한 크론 표현식 제대로 계산하지 않을 수 있습니다 마음에.

public class TestJob implements Job { 

    @Override 
    public void execute(JobExecutionContext context) throws JobExecutionException { 

     context.getPreviousFireTime(); 
    } 
} 

당신이 context.getTrigger().getPreviousFireTime()을 사용하는 경우에 실행되는 작업의 트리거 시간을 가질 것입니다 : 당신이 org.quartz 사용하는

경우
+0

이것은주기적인 발화에만 적용됩니다. 'subsequentNextValidTime'이 없거나 발사가 불규칙한 경우 (예 : 10, 12, 11, 17, 37 분에 화재)? –

2

cron-utils에서

+0

안녕하세요 Joao, 작업을 실행하지 않아도 작동합니다 (예 : 서버 오프라인)? – Marin

+1

@NunoMarinho 예, 이것은 단순히 cron 표현식에서 이전 날짜를 계산합니다. 라이브러리 자체는 cron 표현으로 무엇을하고 있는지 알지 못합니다. 이 라이브러리는 실행될 작업이나 작업을 예약하지 않으며 cron 표현식을 기반으로 날짜를 계산합니다. 오랫동안이 라이브러리를 사용하지는 않았지만 사용 후 필요에 맞게 응용 프로그램을 철저히 테스트하십시오. –

+0

Obrigado João : D – Marin

0

, context.getPreviousFireTime();

예 사용할 수 있습니다 순간.