I’d like my plugin to execute a task each day at a fixed hour, let’s say midnight. To do so when my plugin starts, I submit to the TaskBuilder my task with as an interval 1 day. But for my task to be executed at midnight, I’d like to set as a delay the time until next midnight.
I tried to do so but it the delay is never correct.
taskBuilder
.execute(new MyRunnable())
// 8640000 ms = 1 day
.delay(8640000L - Calendar.getInstance().getTime().getTime() % 8640000L, TimeUnit.MILLISECONDS)
.interval(1, TimeUnit.DAYS)
.submit(this);
This isn’t an async task, is it?
My guess is, that sync tasks are converting all time values into game-ticks, and rely on them. That would mean if the server isn’t running at exactly 20tps all the time, your interval gets longer or shorter…
Async tasks don’t rely on game ticks, they work with the system-time.
So I’d suggest you to try to create an async task, and (if u need Sponge-API access) sync again by creating another sync-task within that async task… If you understand what i mean
It’s late, and my English is bad, so apologize that sloppy explanation ^^
In Java 8 never use java.util.Calendar or java.util.Date! Both where added to Java a long time ago and have serious flaws. Java 8 finally added a useful API that should be used instead.
Calculating the duration between two fixed times is surprisingly complex as you need to take leap seconds and daylight saving times into account. Luckily that is all possible with the new API; an example is given here.
To actually run the task, you can use the scheduler directly {see @simon816’s answer).
I don’t think what @Blue mentioned is required, if the delay or interval is specified using the interval/delay(amount, unit) methods then it will use real time instead of ticks to determine when the task has to be run.
The problem is the calculation of the delay time - the interval is easy, but the server could be rebooted at any time of day, and calculating the time left until midnight for the delay is the crux of the problem here.
With LocalDateTime you can calculate the time between two moments. That means, each times the server boot, you calculate the time until the next midnight.
EDIT: I have done something like that with my plugin.
This is actually not correct. I designed the sync scheduler to go off real time if you give it a value in real time (i.e. using delay or interval). To go based of ticks you have to use delayTicks or intervalTicks. Because it is a sync scheduler it will not be exactly on time, but near enough. it likely won’t be more than 50ms out.