3 回答

TA貢獻1815條經驗 獲得超13個贊
Runnable
將您需要完成的工作定義為Runnable.
然后使用 aScheduled ExecutorService每分鐘左右運行一次,檢查當前日期與目標日期。如果倒計時已增加,請更新 GUI 中的顯示。如果沒有,什么也不做,Runnable再過一分鐘再運行。
請參閱有關執行程序的 Oracle 教程。
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(); // Use a single thread, as we need this to run sequentially, not in parallel.
ses.scheduleWithFixedDelay( r , 0L , 1L , TimeUnit.MINUTES ); // Pass the `Runnable`, an initial delay, a count to wait between runs, and the unit of time for those two other number arguments.
Runnable每次安排一個新的而不是自動重復會更有效,因此將延遲設置為計算出的時間量,直到下一個午夜。這樣,執行者會整天睡覺,而不是每分鐘都在運行。但是,如果用戶的時鐘更新到顯著不同的當前時間,或者用戶當前的默認時區發生變化(如果您依賴于默認時區而不是明確設置),那么這種方法可能會出現問題。鑒于這Runnable需要做的事情很少(只需檢查當前日期和計算剩余天數),沒有實際理由不讓它每分鐘或每兩分鐘運行一次(但您對用戶的最新更新的最小容忍度是多長時間 - 您的業務政策應用程序的管理)。
LocalDate
該類LocalDate表示沒有時間、沒有時區或從 UTC 偏移的僅日期值。
時區對于確定日期至關重要。對于任何給定的時刻,日期在全球范圍內因區域而異。例如,法國巴黎午夜過后幾分鐘是新的一天,而魁北克蒙特利爾仍然是“昨天” 。
如果未指定時區,JVM 會隱式應用其當前默認時區。該默認值可能會在運行時(!)期間隨時更改,因此您的結果可能會有所不同。最好將您想要/預期的時區明確指定為參數。
以、或等格式指定適當的時區名稱。永遠不要使用 2-4 個字母的縮寫,例如或因為它們不是真正的時區,不是標準化的,甚至不是唯一的(?。?。Continent/RegionAmerica/MontrealAfrica/CasablancaPacific/AucklandESTIST
ZoneId z = ZoneId.of( "Asia/Kolkata" ); // Or ZoneId.systemDefault() to rely on the JVM’s current default time zone.
LocalDate today = LocalDate.now( z );
例子
這是完整的例子。有關更多信息,請搜索堆棧溢出。的使用ScheduledExecutorService已經被介紹過很多次了。
package work.basil.example;
import java.time.Instant;
import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class DailyCountdown implements Runnable {
private LocalDate dueDate;
private Long daysRemaining;
public DailyCountdown ( LocalDate dueDate ) {
this.dueDate = dueDate;
}
@Override
public void run () {
try {
System.out.println( "DEBUG - Running the DailyCountdown::run method at " + Instant.now() );
ZoneId z = ZoneId.of( "America/Montreal" ); // Or ZoneId.systemDefault() to rely on the JVM’s current default time zone.
LocalDate today = LocalDate.now( z );
Long count = ChronoUnit.DAYS.between( today , this.dueDate );
if ( Objects.isNull( this.daysRemaining ) ) {
this.daysRemaining = ( count - 1 );
}
if ( this.daysRemaining.equals( count ) ) {
// Do nothing.
} else {
// … Schedule on another thread for the GUI to update with the new number.
this.daysRemaining = count;
}
} catch ( Exception e ) {
// Log this unexpected exception, and notify sysadmin.
// Any uncaught exception reaching the scheduled executor service would have caused it to silently halt any further scheduling.
}
}
public static void main ( String[] args ) {
// Put this code where ever appropriate, when setting up your GUI after the app launches.
Runnable r = new DailyCountdown( LocalDate.of( 2018 , Month.FEBRUARY , 15 ) );
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleWithFixedDelay( r , 0L , 1L , TimeUnit.MINUTES );
// Be sure to gracefully shutdown the ScheduledExecutorService when your program is stopping. Otherwise, the executor may continue running indefinitely on the background thread.
try {
Thread.sleep( TimeUnit.MINUTES.toMillis( 7 ) ); // Sleep 7 minutes to let the background thread do its thing.
} catch ( InterruptedException e ) {
System.out.println( "The `main` thread was woken early from sleep." );
}
ses.shutdown();
System.out.println( "App is exiting at " + Instant.now() ) ;
}
}

TA貢獻1796條經驗 獲得超10個贊
您可以java.util.Timer為此使用類。
在下面的程序中,我采取了不同的方法。我沒有使用開始日期。我只需每天獲取當前日期,然后對照目標日期(在本例中為“2019-02-10”)檢查它。看看這是否適合您的要求。
(FIVE_SECONDS_IN_MILLISECONDS用于測試程序。)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class Scheduler {
private static final long ONE_DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
private static final long FIVE_SECONDS_IN_MILLISECONDS = 1000 * 5;
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
TimerTask timerTask = new TimerTask() {
@Override
public void run() {
Calendar c = Calendar.getInstance();
String dateString = sdf.format(c.getTime());
System.out.println(dateString);
if (dateString.equals("2019-02-10")) {
System.out.println("Date reached!");
}
}
};
Timer timer = new Timer();
timer.schedule(timerTask, 0, ONE_DAY_IN_MILLISECONDS/*FIVE_SECONDS_IN_MILLISECONDS*/);
}
}

TA貢獻1844條經驗 獲得超8個贊
Java 8的time-API,你可以輕松實現。
for (LocalDate date = startDate; date.isBefore(endDate); date = date.plusDays(1))
{
...
}
添加回答
舉報