简体   繁体   English

如何跟踪Java中的日期更改

[英]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 implement 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. Quartz可能是Java世界中最常用的调度程序,但是如果你已经在使用该框架,那么Spring有一些有趣的调度功能。

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). 无论您选择哪种调度程序,通常都会指定要执行的操作(有时称为“作业”)及其发生的时间(Quartz术语中的“触发器”)。 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. 作为库,您可以使用Quartz和set触发器在每晚午夜运行。 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. 或者,你可以通过使用一个单独的线程来实现Quartz自己做的事情,然后一直睡到下一个午夜。

The answer to this question used to be Quartz . 这个问题的答案曾经是Quartz It is the defacto standard for scheduling in Java. 它是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. 如果您不关心作业的集群调度或JDBC存储,则quartz可能过度。

Thankfully Spring 3.0 comes with new scheduling features. 值得庆幸的是,Spring 3.0带有新的调度功能。 These allow the simple 'do this evey 30 seconds' or 'do this everyday at midnight' types of scheduling without using quartz. 这些允许简单的'做这个evey 30秒'或'每天午夜做'这种类型的日程安排,而不使用石英。 If you are already using spring it is pretty easy to set up. 如果您已经使用spring,那么设置非常简单。

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. 这将导致每天午夜在名为'anotherObject'的bean上调用方法'anotherMethod'。 More information can be found on spring's site: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/scheduling.html 有关更多信息,请访问spring网站: 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. 它基本上是一个Timer类。

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. 当首次通过Start()方法执行类时,代码获取当前时间的日期时间,然后获取午夜的datetime对象并减去2次,以便给出一个时间直到午夜。

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. 这将使间隔为24.当此计时器到期时,它将被重置并无限期地重复。

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). 如果你不想要Quartz或任何其他类似的框架,你可以简单地使用ScheduledExecutorServicescheduleAtFixedRate方法(这里有一个如何在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. 正如Jarnbjo所说:这将无法生存夏令时开关和闰秒。 So be aware of this, when using the Executor. 因此,在使用Executor时请注意这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM