Question

I'm trying to figure out the logic to set an arbitrary time, and then have that time "play back" at different speeds (like .5x or 4x real time).

Here is the logic I have thus far, which will playback the time at normal speed:

import java.util.Calendar;


public class Clock {


    long delta;
    private float speed = 1f;

    public Clock(Calendar startingTime) {
        delta = System.currentTimeMillis()-startingTime.getTimeInMillis();
    }

    private Calendar adjustedTime() {
        Calendar cal = Calendar.getInstance();

        cal.setTimeInMillis(System.currentTimeMillis()-delta);

        return cal;

    }

    public void setPlaybackSpeed(float speed){
        this.speed  = speed;
    }

    public static void main(String[] args){


        Calendar calendar = Calendar.getInstance();
        calendar.set(2010, 4, 4, 4, 4, 4);
        Clock clock = new Clock(calendar);

        while(true){
            System.out.println(clock.adjustedTime().getTime());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }


}

I'm having trouble figuring out where the "speed" attribute needs to be used in the logic.

Was it helpful?

Solution

The following code gives an example of how you design such a clock, which has an internal state of a double spped and long startTime. It exposes a publish method getTime(), which will return the adjusted time in millisecond since Midnight, Jan 1st, 1970. Note that the adjustment happens after the startTime.

The formula to calculate the adjusted time is simple. First take the real timedelta by subtracting currentTimeMillis() by startTime, then multiply this value by speed to get the adjusted timedelta, then add it to startTime to get your result.

public class VariableSpeedClock {

    private double speed;
    private long startTime;

    public VariableSpeedClock(double speed) {
        this(speed, System.currentTimeMillis());
    }

    public VariableSpeedClock(double speed, long startTime) {
        this.speed = speed;
        this.startTime = startTime;
    }

    public long getTime () {
        return (long) ((System.currentTimeMillis() - this.startTime) * this.speed + this.startTime);
    }

    public static void main(String [] args) throws InterruptedException {

        long st = System.currentTimeMillis();
        VariableSpeedClock vsc = new VariableSpeedClock(2.3);

        Thread.sleep(1000);

        System.out.println(vsc.getTime() - st);
        System.out.println(System.currentTimeMillis() - st);

    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top