Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring cron expression - how to get last execution time

In Spring I can get the nextExecution time using:

final CronSequenceGenerator generator = new CronSequenceGenerator(cronExpression);
final Date nextExecutionDate = generator.next(new Date());

But how to get the last execution time from the cron expression ?

like image 203
AliR Avatar asked Nov 21 '22 05:11

AliR


1 Answers

It uses binary search to find the last execution time.

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.springframework.scheduling.support.CronExpression;

public class CronTest {

    @Test
    void cronTest() {
        CronExpression expression = CronExpression.parse("1 0/10 * * * ?");
        ZonedDateTime nextTime = expression.next(ZonedDateTime.now());
        assertNotNull(nextTime);
        ZonedDateTime prevTime = getPrevTime(expression, nextTime, nextTime.minusDays(1));
        assertEquals(nextTime.minusMinutes(10), prevTime);
    }

    private ZonedDateTime getPrevTime(CronExpression expression, ZonedDateTime nextTime, ZonedDateTime mayPrevTime) {
        ZonedDateTime start = mayPrevTime;
        ZonedDateTime end = nextTime;
        while (start.isBefore(end)) {
            ZonedDateTime middle = end.minusSeconds(
                TimeUnit.MILLISECONDS.toSeconds(Duration.between(start, end).toMillis() / 2));
            ZonedDateTime tmpNextTime = expression.next(middle);
            if (Objects.equals(tmpNextTime, nextTime)) {
                end = middle.minusSeconds(1);
            } else {
                start = middle.plusSeconds(1);
            }
        }
        return start;
    }
}
like image 64
Gan Avatar answered Mar 05 '23 05:03

Gan