12

JavaでCron式から「最終起動時間」を見つける方法はありますか?

たとえばnow = 25-Apr-2010 10PM、 で、cron 式が0 15 10 ? * *(quartz) の場合、 を返す必要があり25-Apr-2010 10:15AMます。

ノート:

  1. 標準の cron 式 (Unix や Quartz など) を使用するか、あまり一般的ではない式を使用するかは、正しい「最終起動時刻」を取得できる場合は気にしません。
  2. また、トリガーが発火していない可能性があるため、文字通り「最終発火時間」ではありませんが、論理的には、最後に発火した(発火した)時期を知る方法があるはずです。
4

9 に答える 9

3

まず、これをサポートする既存のライブラリを知りません。Quartz はそうかもしれませんが、標準の Java クラス ライブラリは確かにそうではありません。

第二に、厳密に言えば本来求められていることは不可能です。ライブラリがあなたに伝えることができる最善のことは、cron 式起動した、または起動したはずであるということです。cron 式が実際に起動された最後の時間を (理論的には) 教えてくれる唯一のものは、スケジューラーのインスタンス自体です。

于 2010-04-26T04:21:17.490 に答える
2

Quartz には、cron 式のライブラリサポートがあるようです。

というメソッドを持つCronExpression クラスの Javadoc を参照してくださいgetTimeBefore。すなわち、

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

これが機能するかどうかは、Quartz のバージョンに依存する場合があります。

最新のソース (執筆時点ではバージョン 2.3.0) を見ると、このメソッドは実装されておらず、常に null を返します。

于 2010-04-27T05:34:15.987 に答える
1

Quartzで私が見つけた解決策は、トリガーの1つの時間間隔に戻って、次の発火時刻を計算することです。すべてのトリガーを反復処理することにより、トリガーが過去に発生したはずの最新の時刻を判別できます。


各発砲の間隔を計算します。

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

過去の間隔までの1回の次の発火時間を見つけます。

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 = ...
    }
}

これをヘルパーメソッドまたはクラスにリファクタリングするための演習として、読者に任せます。私は実際に上記のアルゴリズムをサブクラス化された委任トリガーで使用し、それを以前の起動時間でソートされたセットに配置します。

于 2012-01-19T16:24:18.540 に答える
0

org.quartz を使用している場合は、使用可能ですcontext.getPreviousFireTime();

例:

public class TestJob implements Job {

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

        context.getPreviousFireTime(); 
    }
}

を使用している場合はcontext.getTrigger().getPreviousFireTime()、現在実行中のジョブのトリガー時刻が表示されます。

于 2016-11-25T08:55:40.617 に答える
-1
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);
        }
    }
}

ソースコードhttps://github.com/devbhuwan/cron-micro-utils

于 2015-07-06T05:46:21.073 に答える
-1

その実用的なソリューション

   pom :
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>

   javaCode:
        //Provide your format of date  want
        String format="dd-MMM-YYYY hh:mm:ss";
        //Provide your cron expression you want
        String cronExpression="* * 12 ? * FRI *";
        SimpleDateFormat sdf=new SimpleDateFormat(format);
        CronExpression expression = new CronExpression(cronExpression);
        Date  currentDate=new Date();
        Date nextDate=expression.getNextValidTimeAfter(currentDate);
        long interval = nextDate.getTime()-currentDate.getTime();
        Date previousDate= new Date(currentDate.getTime() - interval);
        System.out.Println(sdf.format(previousDate));

ここでは、現在の時刻と次の発射時刻の差を取得し、現在の時刻からこの差の時間を除外して、最後に発射された時刻を取得します

于 2018-07-12T11:01:54.210 に答える