19

I'm relatively new to Java and I've pick up a project to work on. However, I've run into a block. I need a method to run at a certain times throughout the day. I've done quite a bit of searching but I can't find anything that seems like it would do the trick. I've run into the Timer class but it appears to run at certain intervals. The Scheduler class, appeared to have the same issue. I also came across Quartz but I think I need something more lightweight and I could only see how to do things at intervals.

Perhaps, just because I'm new, I've missed some things that could help me in these classes, but I'm really stuck and could use some help.

If someone could point me to a class that will run something at a certain time of day, everyday (bonus points for being able to cancel the event), and show me how to correctly use the class, that would be awesome!

TL;DR: Need a class that does something at a time of day, not at an interval because the program may be restarted multiple times throughout the day.

Austin Moore
  • 1,414
  • 6
  • 20
  • 43

3 Answers3

33

try the TimerTask class

for more info check out http://oreilly.com/java/archive/quartz.html

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class ReportGenerator extends TimerTask {

  public void run() {
    System.out.println("Generating report");
    //TODO generate report
  }

}

class MainApplication {

  public static void main(String[] args) {
    Timer timer = new Timer();
    Calendar date = Calendar.getInstance();
    date.set(
      Calendar.DAY_OF_WEEK,
      Calendar.SUNDAY
    );
    date.set(Calendar.HOUR, 0);
    date.set(Calendar.MINUTE, 0);
    date.set(Calendar.SECOND, 0);
    date.set(Calendar.MILLISECOND, 0);
    // Schedule to run every Sunday in midnight
    timer.schedule(
      new ReportGenerator(),
      date.getTime(),
      1000 * 60 * 60 * 24 * 7
    );
  }//Main method ends
}//MainApplication ends
Shantanu Nandan
  • 1,438
  • 8
  • 30
  • 56
dov.amir
  • 11,489
  • 7
  • 45
  • 51
  • 3
    +1: I love quartz, too. But using it vs. starting the task with cron makes it your responsibility that the app never crashes, automatically restarts if it still crashes, etc. – Daniel Aug 06 '11 at 07:49
  • 2
    Note that this is broken after a change in DST! The timer will then run one hour late or fast, here at 1am or 11pm (depending whether it was started in summer and transitions to winter time, or the reverse). – Philipp Sep 12 '13 at 15:40
  • I had add date.set(Calendar.AM_PM, Calendar.AM); or PM to make it work at exact time I expected. – Valerio Emanuele Sep 12 '13 at 21:56
  • Yes, the date.set(Calendar.HOUR, 0); should be date.set(Calendar.HOUR_OF_DAY, 0); if you use 24 hour format – perzsa Aug 16 '17 at 12:12
5

I'd strongly suggest, if at all possible, that the best approach would be to invoke your script or Java application using your OS's scheduler: for example, "cron" in *nix, or "task scheduler" in Windows.

paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • I would second that suggestion. Why reimplement everything, and worry about managing the Java app at all? @Eegabooga do you really _need_ this in Java? Lightweight solutions can be implemented if you need them, but it is reinventing a lot and likely will not be as robust. – Ray Toal Aug 06 '11 at 07:02
  • Thank you all for your replies. However, I'm almost 100% sure that this needs to be within Java. It's not the program that needs relaunching at a certain time everyday, it's an action that the program does. Even if cron could do this, this program is not for me but someone else. What I am making is a plugin for a game server and the plugin hooks into this guy's server. If it is possible, I could send him the cron files he would need if you think this would work, but remember I need an method to run within the program, not the program it's self (sorry if syntax is wrong, still learning) – Austin Moore Aug 06 '11 at 14:55
  • Ok I see now that I can run a cronjob through Java with Quartz. – Austin Moore Aug 06 '11 at 17:24
2

One possibility could be to use an external scheduler - depending on desired accuracy. On UNIX use CRON, on Windows use the Windows Scheduler. That nicely isolates timing from doing.

You could use a Timer and create a simple class that checks the time every minute or 5 minutes depending on desired granularity. It would be very lightweight.

Richard Corfield
  • 717
  • 6
  • 19