0

I am trying to create a custom clock in java. On the application initialization, the clock will be set to the system time and will tick normally. But it should also have the capability to start ticking from a custom time.

public class DockerClock {

static Clock clock = Clock.tickMillis(TimeZone.getDefault().toZoneId());
static Instant instant = Instant.now(clock);

static Instant prev = instant;

public Clock getClock() {
    return this.clock;
}

public Instant getInstant() {
    return instant;
}

public void setTime() {
    instant = Instant.now(this.clock).plusSeconds(10);
    Clock newClock = Clock.fixed(instant, TimeZone.getDefault().toZoneId());
    this.clock = Clock.offset(newClock, Duration.ofMinutes(5));

}

But the problem I am facing is that on calling the setTime method, the clock is fixed (and rightly so) at that very instant.

What should be the ideal approach here? In the end all I want to make is a working clock with ability to drift forward/backward with an offset I provide and continue ticking like a clock.

UPDATE: after doing Clock.offset(baseClock, Duration...), I am able to make the clock go back and forward according to the offset I pass to it. However, while the program is running, if I change the system time, my implemented clock starts showing time according to the system clock, ie it starts again from the changed system time.

Is there any possible way I can de-link it with my system clock altogether? I want to sync it with the system cock only in the starting and never again!

Swapnil Pandey
  • 577
  • 3
  • 8
  • 25
  • 1
    If you want it to continue ticking, then you don't want a `Clock.fixed` "that always returns the same instant." (https://docs.oracle.com/javase/8/docs/api/java/time/Clock.html#fixed-java.time.Instant-java.time.ZoneId- ) Instead of `Clock.offset(newClock` try `Clock.offset(this.clock` – racraman Aug 29 '19 at 11:05
  • Can't you just have a clock running internally and normally and define an offset that's added to the current time whenever you need to get a current `Instant`? That's basically what the `OffsetClock` instance you get from ` Clock.offset(...)` is doing (without the ability to change the offset) – Thomas Aug 29 '19 at 11:48
  • Tip, instead of `TimeZone.getDefault().toZoneId()` just use `ZoneId.systemDefault()`. Don’t involve the poorly designed and long outdated `TimeZone` class. – Ole V.V. Aug 30 '19 at 07:13
  • Thank you @racraman. Your suggestion helped. Please see the update section on the original question. – Swapnil Pandey Sep 06 '19 at 06:19

1 Answers1

0

You can schedule your job like this:

ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        // TODO update your clock to current time.
    }
}, 0, 1, TimeUnit.SECONDS);

You can schedule this thread to run every 1 second or minute depending on your requirement.

Vivek Mangal
  • 532
  • 1
  • 8
  • 24
  • Which thread? I want a ticking clock so that I can get time from it any moment (precise to milliseconds). I also have the need to move it forward/backward time and again by some offset. – Swapnil Pandey Aug 29 '19 at 11:05
  • This might help : https://stackoverflow.com/questions/44275542/clock-that-is-able-to-tick – Vivek Mangal Aug 29 '19 at 12:02