14
  • my database having 10 18 16 ? * SUN,MON,WED,FRI * cron expression then how to convert into Java date.
  • how to comparing with present day time.
  • and one more is how to compare to cron expressions i.e. 10 18 16 ? * SUN,MON,WED,FRI * and 0 30 9 30 * ?
  • please explain the sample code using quartz or spring scheduling.
sashimi
  • 1,224
  • 2
  • 15
  • 23
user3599212
  • 429
  • 2
  • 6
  • 18

4 Answers4

25

Please use:

import org.springframework.scheduling.support.CronSequenceGenerator;

final String cronExpression = "0 45 23 * * *";
final CronSequenceGenerator generator = new CronSequenceGenerator(cronExpression);
final Date nextExecutionDate = generator.next(new Date());

...and then I suggest use Joda DateTime for date comparison.

Matt
  • 529
  • 1
  • 5
  • 10
  • Excellent! Thank you very much! – DmitryKanunnikoff Jun 23 '17 at 23:53
  • Spring implementation of cron actionally lacks one feature - 'day' and 'day-of-week' fields are combined by AND logic, not by OR as in cron. – Eugene May 28 '18 at 13:37
  • @Eugene i don't think tat this is a disadvantage... you can easily simulate "OR"-ed expressions by providing 2 expression. With AND you have the advantage that you can execute e.g. "every 2nd thuesday at..." – Michael Mangeng Jun 26 '18 at 15:07
  • 1
    Deprecated: need to use ```CronExpression generator = CronExpression.parse(cronExpression)``` – myborobudur Sep 20 '22 at 15:56
10

I wrote a small class for handling cron expressions, available here: https://github.com/frode-carlsen/cron

Based on Joda-time, but should be fairly easy to port to Java8 time api. This also makes it possible to embed in unit tests, do simulations etc by adjusting the DateTime offset in Joda-time.

It also has pretty good test coverage (was done as TDD Kata).

Update Now supports java 8 time api as well thanks to a contribution from github user https://github.com/zemiak. In both cases, the expression parser is a single, tiny class which can easily be copied into your own project.

f.carlsen
  • 445
  • 4
  • 8
  • 1
    Is it on maven central? – oshai Jan 22 '15 at 13:42
  • No, it's just a single class only depending on joda-time, so I haven't bothered. Feel free to fork or copy – f.carlsen Mar 27 '15 at 10:06
  • 2
    Hey, this very cool. I've used your code to replace cron-utils which depend on guava, an over 2MB monster jar in my project: https://github.com/actframework/actframework/blob/master/src/main/java/fc/cron/CronExpression.java – Gelin Luo Mar 25 '16 at 07:08
  • Seems guava dependency is no longer required by cron-utils. Release 5.0.0 relies on JDK8 and no longer needs guava nor jodatime. – sashimi Aug 08 '16 at 04:33
  • This was exactly what I was looking for. A small class that does cron-like parsing. Thank you very much! – gdany Nov 13 '20 at 15:38
7

You may want to look into the org.quartz.CronExpression class in the Quartz API.

Please note that you cannot simply compare a cron expression with a date because the cron expression (typically) represents a sequence of various dates. In any case, you may find the following methods useful:

public boolean isSatisfiedBy(Date date)
public Date getNextValidTimeAfter(Date date)

As for comparing two cron expressions, what would you like to compare? The only thing that IMO makes sense to compare are the next 'trigger' dates, i.e. dates obtained from getNextValidTimeAfter([some reference date]) calls.

Jan Moravec
  • 1,808
  • 1
  • 15
  • 18
  • Does it based on Joda-Time? or what?! – Dr.jacky May 11 '15 at 08:47
  • We want to convert cron to java date. What is the method to achieve? – Dr.jacky May 11 '15 at 11:35
  • 2
    You typically cannot convert a cron expression to a single Date instance because a cron expression usually represents a series of Dates. To obtain the the Date series, I think you can repeatedly call the getNextValidTimeAfter(Date) method and use the returned values as the input value for the next call. To answer your former question, Quartz API does not use Joda-Time, it uses java.util Date/Calendar APIs. – Jan Moravec May 11 '15 at 11:53
6

Perhaps you can check cron-utils It has some utils to get next/previous execution given certain date, ex.: now. Works with JodaTime, but you could retrieve a JavaDate from there. The library is scheduler agnostic: you just provide a string with a cron expression. Is compatible with JDK6.

sashimi
  • 1,224
  • 2
  • 15
  • 23
  • cron-utils is nice. The only thing is it has guava dependency which is over 2MB – Gelin Luo Mar 25 '16 at 06:29
  • Guava dependency was an issue. Since version 5.0.0 they removed it by migrating to JDK8. Now the library has even less dependencies, since they also got rid off jodatime leveraging new Java support for time. – sashimi Aug 08 '16 at 04:35
  • 1
    sounds good. But it now locked to Java8. I end up with using this single file parser: https://github.com/frode-carlsen/cron/blob/master/src/main/java/fc/cron/CronExpression.java – Gelin Luo Aug 08 '16 at 06:38
  • Sure, is an option :) Eventually you need to bind to some JDK. – sashimi Aug 08 '16 at 19:29
  • Thanks for this suggestion. I needed joda-time support in core-utils. Hence I choose the 4.1.3 version. Works as expected. – user238607 Aug 04 '17 at 16:23