-2

I have a written a java code to popup a dialog box every day at 8pm (20:00 hours). However the code worked for the first time only and didn't work later after I changed the time. This is my code:

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JOptionPane;

public class PopUp {

public static void main(String[] args) {
    Timer timer = new Timer();
    TimerTask tt = new TimerTask() {
        @Override
        public void run() {
            Calendar cal = Calendar.getInstance();

            int hour = cal.get(Calendar.HOUR_OF_DAY);
            int min = cal.get(Calendar.MINUTE);
            int sec = cal.get(Calendar.SECOND);

            if (hour == 20 && min == 00 && sec == 0) {
                JOptionPane.showMessageDialog(null, "PopUp Success at "+new Date().toString());
                System.out.println("PopUp Success at "+new Date().toString());
            }
        }
    };
    timer.schedule(tt, 1000, 1000 * 5);
}

}

Is there anything wrong with my code? Plz help me out in solving this issue to popup the dialog box every day at 8pm.

  • 2
    The problem I'm seeing is that this would have to stay running in the background. I know if I got an update I would probably just quit the program and that would be it. Maybe create a bash script that is run on startup which then prompts the user by opening your dialog widow program. https://stackoverflow.com/questions/17394356/how-can-i-make-a-bash-command-run-periodically – Locke Aug 21 '18 at 19:33
  • 1
    There are loads of examples of similar programs out there. Use your search engine. – Ole V.V. Aug 22 '18 at 06:49
  • I had seen a lot of programs out there but none solved my problem. Can you plz give an example or atleast provide a link where I can get the solution? – Ronauk Maharana Aug 22 '18 at 08:28

1 Answers1

2

Is there anything wrong with my code?

Your timer task checks the time, precisely the hour, minute and second. You are scheduling this task with a periodic delay of 5 second (1000 * 5 milliseconds). This means that you are unlikely to hit 20:00:00 exactly. You may for example check at 19:59:57 and then again at 20:00:02, or even 20:00:03 since each check takes a bit of time and timing is never accurate.

Apparently you were lucky the first time but haven’t been the succeeding times.

A possible fix is to use one of the two overloaded scheduleAtFixedRate methods with a period of 1 day. Then your timer task when invoked can trust that the time has come and needs not check. I would specify 1 day as TimeUnit.DAYS.toMillis(1), it’s clearer to read and less error-prone than some multiplication.

You may also consider using the scheduling capability of your operating system rather than coding your own. Reinventing the wheel is often a poor investment.

Calendar is outdated

The Calendar class you are using is long outdated and poorly designed. I recommend you look into java.time, the modern Java date and time API, for a replacement.

Unfortunately scheduleAtFixedRate​(TimerTask, Date, long) takes an argument of a type that is at least as outdated, java.util.Date. To obtain a Date using java.time:

    ZoneId zone = ZoneId.of("Asia/Chungking");
    ZonedDateTime at2000 = LocalDate.now(zone)
            .atTime(LocalTime.of(20, 0))
            .atZone(zone);
    if (at2000.isBefore(ZonedDateTime.now(zone))) {
        // Time has passed for today; use tomorrow
        at2000 = at2000.plusDays(1);
    }
    Date dateForScheduler = Date.from(at2000.toInstant());

Of course use your own time zone where I put Asia/Chungking.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Good to hear. Thx for reporting back. If your time zone uses summer time (daylight saving time) or other changes in time, the fixed rate of 1 day will not give you the correct time across such transitions. Then you will need some other solution. – Ole V.V. Aug 22 '18 at 20:17