package com.jasamedika.medifirst2000.asynctask; import java.util.Calendar; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class YearlyTimer { private final static Logger LOGGER = LoggerFactory.getLogger(YearlyTimer.class); // What to do private final Runnable whatToDo; // when private final int dayOfMonth; private final int hourOfDay; // The current timer private Timer current = new Timer(); public void cancelCurrent() { LOGGER.info("YearlyTimer : Cancel current execution"); current.cancel(); LOGGER.info("YearlyTimer : Removes the timertask so it can be garbage collected"); current.purge(); } public static YearlyTimer schedule(Runnable runnable, int dayOfMonth, int hourOfDay) { LOGGER.info("YearlyTimer : Create a new instance"); return new YearlyTimer(runnable, dayOfMonth, hourOfDay); } private YearlyTimer(Runnable runnable, int day, int hour) { this.whatToDo = runnable; this.dayOfMonth = day; this.hourOfDay = hour; schedule(); } private void schedule() { cancelCurrent(); LOGGER.info("YearlyTimer : Assigning a new instance of Timer, allow the previous Timer to be garbage collected"); current = new Timer(); current.schedule(new TimerTask() { public void run() { try { LOGGER.info("YearlyTimer : Running schedule"); whatToDo.run(); } finally { LOGGER.info("YearlyTimer : Schedule for the next year"); schedule(); } } }, nextDate()); } private Date nextDate() { Calendar runDate = Calendar.getInstance(); runDate.set(Calendar.MONTH, 5); runDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); runDate.set(Calendar.HOUR_OF_DAY, hourOfDay); runDate.set(Calendar.MINUTE, 0); runDate.set(Calendar.SECOND, 0); runDate.set(Calendar.MILLISECOND, 0); runDate.add(Calendar.YEAR, 1); LOGGER.info("YearlyTimer : Set to next year " + runDate.getTime()); return runDate.getTime(); } }