开发者

How to keep track of the change in date in Java

I have an application that needs to do some actions every date change say at midnight. Whenever the date changes the application should be said of the same. Any help regarding how to implem开发者_C百科ent the functionality would be appreciated.


What you're looking for is a scheduler. Quartz is probably the most commonly used scheduler in the Java world, though Spring has some interesting scheduling features if you are already using that framework.

Whichever scheduler you choose, you generally specify an action to occur (sometimes referred to as a "job") and a time for it to happen (a "trigger" in the Quartz terminology). In your case you'd set the trigger to run every day at midnight, and when it fired it would do whatever it was you needed done, as specified by your job.


As a library, you can use Quartz and set triggers to run at midnight every night. I think simple triggers should do the job.

Alternatively, you can implement what Quartz does yourself, by using a separate thread and sleeping until the next midnight.


The answer to this question used to be Quartz. It is the defacto standard for scheduling in Java. It is pretty easy to use but it is a bit heavyweight. If you don't care about clustered scheduling or JDBC storage of the jobs, quartz might be overkill.

Thankfully Spring 3.0 comes with new scheduling features. These allow the simple 'do this evey 30 seconds' or 'do this everyday at midnight' types of scheduling without using quartz. If you are already using spring it is pretty easy to set up.

Example:

<task:scheduler id="scheduler" pool-size="10"/>

<task:scheduled-tasks scheduler="scheduler">
    <task:scheduled ref="anotherObject" method="anotherMethod" cron="* * 00 * * *"/>
</task:scheduled-tasks>

This will cause the method 'anotherMethod' to be called on you bean named 'anotherObject' at midnight everyday. More information can be found on spring's site: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html


You don't need a big bloaty framework. Something like this should work.

import java.util.*;
public class Midnight {
    public static void main(String args[])  {
        MidnightCowboy mc = new MidnightCowboy();
        mc.start();
        // on with you normal program flow (if any) here
    }
}

class MidnightCowboy extends Thread  {
    static final boolean COWS_COME_HOME = false;
    // Whatever data you need should go here

    public void run()  {
        while (! COWS_COME_HOME)  {
            GregorianCalendar now = new GregorianCalendar();
            long nowMilli = now.getTimeInMillis();
            now.add(Calendar.DAY_OF_MONTH, 1);      // probably an easier way to set the time to the next midnight
            now.set(Calendar.HOUR_OF_DAY, 0);   
            now.set(Calendar.MINUTE, 0);
            now.set(Calendar.SECOND, 0);
            now.set(Calendar.MILLISECOND, 0);
            long midnightMilli = now.getTimeInMillis();
            long delta = midnightMilli - nowMilli;
            System.out.println("Waiting " + delta + " milliseconds until midnight.");
            // How many milliseconds until the next midnight?
            try  {
                sleep(delta);
                doSomething();
            } catch (InterruptedException e)  {
                System.err.println("I was rudely interrupted!");
            }
        }
    }

    void doSomething() {
        // whatever
    }
}


If you want a more lightweight solution than a whole library, I found a pretty simple implementation here. It's basically a Timer class.

When the class is first executed via the Start() method, the code obtains a datetime of the current time, then gets a datetime object of midnight and subtracts the 2 times in order to give a time until it is midnight.

With this time, it sets the timer interval and starts the timer. Now when the interval is reached and the timer fires its event, I reset the timer using the same process. This will make the interval for 24. When this timer expires, it is then reset and repeated indefinitely.


If you don't want Quartz or any other Framework like that, you can simply use the scheduleAtFixedRate Method of the ScheduledExecutorService instead (there's an example of how to instantiate one at the JavaDoc).

The only thing you have to think about is how to calculate the beginning of the first day.

Edit

As Jarnbjo mentioned: This won't survive Daylight Saving Time switches and leap-seconds. So be aware of this, when using the Executor.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜