簡體   English   中英

安排任務在特定時間發生(在 Java 中)

[英]Scheduling a task to happen at a specific time (in Java)

我已經為此查看了論壇並且我得到了答案,但它不太適合我的問題。

所以事情是(這是為了大學作業):我必須安排一個任務在未來的特定時間發生(由程序的用戶定義)。

首先,我開始嘗試通過以這種方式選擇日期來完成這項工作:

//this is my main class

        DateFormat dateFormatter = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss");
        String year = String.valueOf(LocalDate.now().getYear());
        String month = String.valueOf(LocalDate.now().getMonthValue());
        String day = "05";
        Date date = dateFormatter.parse(year + "-" + month + "-" + day + " 02:24:08");

        Timer timer = new Timer();
        timer.schedule(new MyTimeTask("Patrick"), date);

//the class MyTimeTask:

        public class MyTimeTask extends TimerTask {
           private String name;
           public MyTimeTask(String name) {
              this.name = name;
           }
           public void run() {
              System.out.println(this.name);
           }
        }

問題是:這不會在我想要的時間運行。 相反,它會在我運行文件時自動運行,無論我選擇的日期在未來多遠。

我哪里錯了?

謝謝你。

您的代碼中有幾個問題需要解決。

首先是: new SimpleDateFormat("yyyy-mm-dd hh:mm:ss") 仔細看看你的模式。 yyyy-mm-dd hh:mm:ss轉換為year-minute-day hour:minute:second 我相信你想要年后的一個月,而不是一分鍾。 yyyy-MM-dd hh:mm:ss進行簡單更改即可解決此問題。

其次, LocalDate.now().getMonthValue() (目前)返回6 (而不是06 ),因此您的模式yyyy:MM:dd與它不匹配。 要解決此問題,我會將您的年份和月份字符串組合成一個變量,以便您可以使用DateTimeFormatter將月份格式化為MM

String yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));

現在您可以像這樣解析您的日期:

Date date = dateFormatter.parse(yearMonth + "-" + day + " 02:24:08");

我要做的最后一件事(這不是完全必要的)是指定給定時間是前子午線還是后子午線,或者將小時更改為軍用時間。 為此,您只需將“aa”添加到日期格式化程序的末尾即可。

這是最終的代碼:

DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd hh:mm:ssaa");
String yearMonth = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
String day = "04";
Date date = dateFormatter.parse(yearMonth + "-" + day + " 02:24:08PM");

Timer timer = new Timer();
timer.schedule(new MyTimeTask("Patrick"), date);

java.time

您已經在使用 java.time 中的LocalDate ,現代 Java 日期和時間 API。 那挺好的。 Timer.schedule()需要老式java.util.Date object 時:

  1. 使用 java.time 進行時間計算。
  2. 轉換為現代Instant
  3. 在調用需要Date的舊版 API 之前將Instant轉換為Date

為了您的目的,我建議:

    ZoneId zone = ZoneId.systemDefault();
    Instant scheduleTime = YearMonth.now(zone)
            .atDay(5)
            .atTime(LocalTime.of(2, 24, 8))
            .atZone(zone)
            .toInstant();
    Date oldfashionedDate = Date.from(scheduleTime);

    System.out.println(oldfashionedDate);

Output 剛才在我的時區運行時:

2020 年 6 月 5 日星期五 02:24:08 CEST

你的代碼出了什么問題?

  1. 您的格式模式字符串yyyy-mm-dd hh:mm:ss是錯誤的。 格式模式字母區分大小寫,因此使用大寫MM或小寫mm以及使用HHhh都會有所不同。 我相信這是您的計時器過早觸發的原因。
  2. 作為清晰代碼的問題,我更喜歡將時區傳遞給LocalDate.now()即使您傳遞的時區是ZoneId.systemDefault()
  3. 不要閱讀LocalDate.now()兩次。 如果您的代碼在午夜運行,您可能會得到兩個不同的日期,並且最終會出現不一致的結果。 讀取一次日期並在代碼的 rest 中使用該讀數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM