You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
3.8 KiB
127 lines
3.8 KiB
package seng302.Model;
|
|
|
|
import com.github.bfsmith.geotimezone.TimeZoneLookup;
|
|
import com.github.bfsmith.geotimezone.TimeZoneResult;
|
|
import javafx.animation.AnimationTimer;
|
|
import javafx.beans.property.SimpleStringProperty;
|
|
import javafx.beans.property.StringProperty;
|
|
import seng302.GPSCoordinate;
|
|
|
|
import java.time.Duration;
|
|
import java.time.LocalDateTime;
|
|
import java.time.ZoneId;
|
|
import java.time.ZonedDateTime;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.temporal.ChronoUnit;
|
|
import java.util.Date;
|
|
|
|
/**
|
|
* Created by Gondr on 19/04/2017.
|
|
*/
|
|
public class RaceClock implements Runnable {
|
|
private long lastTime;
|
|
private final ZoneId zoneId;
|
|
private ZonedDateTime time;
|
|
private ZonedDateTime startingTime;
|
|
private final StringProperty timeString;
|
|
private StringProperty duration;
|
|
|
|
public RaceClock(ZonedDateTime zonedDateTime) {
|
|
this.zoneId = zonedDateTime.getZone();
|
|
this.timeString = new SimpleStringProperty();
|
|
this.duration = new SimpleStringProperty();
|
|
this.time = zonedDateTime;
|
|
setTime(time);
|
|
}
|
|
|
|
public static ZonedDateTime getCurrentZonedDateTime(GPSCoordinate gpsCoordinate) {
|
|
TimeZoneLookup timeZoneLookup = new TimeZoneLookup();
|
|
TimeZoneResult timeZoneResult = timeZoneLookup.getTimeZone(gpsCoordinate.getLatitude(), gpsCoordinate.getLongitude());
|
|
ZoneId zone = ZoneId.of(timeZoneResult.getResult());
|
|
return LocalDateTime.now(zone).atZone(zone);
|
|
}
|
|
|
|
public void run() {
|
|
new AnimationTimer() {
|
|
@Override
|
|
public void handle(long now) {
|
|
updateTime();
|
|
}
|
|
}.start();
|
|
}
|
|
|
|
/**
|
|
* Sets time to arbitrary zoned time.
|
|
*
|
|
* @param time arbitrary time with timezone.
|
|
*/
|
|
private void setTime(ZonedDateTime time) {
|
|
this.time = time;
|
|
this.timeString.set(DateTimeFormatter.ofPattern("HH:mm:ss dd/MM/YYYY Z").format(time));
|
|
this.lastTime = System.currentTimeMillis();
|
|
if(startingTime != null) {
|
|
long seconds = Duration.between(startingTime.toLocalDateTime(), time.toLocalDateTime()).getSeconds();
|
|
if(seconds < 0)
|
|
duration.set(String.format("Starting in: %02d:%02d:%02d", -seconds/3600, -(seconds%3600)/60, -seconds%60));
|
|
else
|
|
duration.set(String.format("Time: %02d:%02d:%02d", seconds/3600, (seconds%3600)/60, seconds%60));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets time to given UTC time in seconds from Unix epoch, preserving timezone.
|
|
* @param time UTC time
|
|
*/
|
|
public void setUTCTime(long time) {
|
|
Date utcTime = new Date(time);
|
|
setTime(utcTime.toInstant().atZone(this.zoneId));
|
|
}
|
|
|
|
public ZonedDateTime getStartingTime() {
|
|
return startingTime;
|
|
}
|
|
|
|
public void setStartingTime(ZonedDateTime startingTime) {
|
|
this.startingTime = startingTime;
|
|
}
|
|
|
|
/**
|
|
* Get ZonedDateTime corresponding to local time zone and given UTC time.
|
|
* @param time time in mills
|
|
* @return local date time
|
|
*/
|
|
public ZonedDateTime getLocalTime(long time) {
|
|
Date utcTime = new Date(time);
|
|
return utcTime.toInstant().atZone(this.zoneId);
|
|
}
|
|
|
|
/**
|
|
* Updates time by duration elapsed since last update.
|
|
*/
|
|
private void updateTime() {
|
|
this.time = this.time.plus(Duration.of(System.currentTimeMillis() - this.lastTime, ChronoUnit.MILLIS));
|
|
this.lastTime = System.currentTimeMillis();
|
|
setTime(time);
|
|
}
|
|
|
|
public String getDuration() {
|
|
return duration.get();
|
|
}
|
|
|
|
public StringProperty durationProperty() {
|
|
return duration;
|
|
}
|
|
|
|
public String getTimeZone() {
|
|
return zoneId.toString();
|
|
}
|
|
|
|
public ZonedDateTime getTime() {
|
|
return time;
|
|
}
|
|
|
|
public StringProperty timeStringProperty() {
|
|
return timeString;
|
|
}
|
|
}
|