package geniusweb.progress; import java.util.Date; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonTypeName; import geniusweb.deadline.DeadlineTime; /** * keeps track of progress towards the Deadline and the time/rounds left. * immutable. However, the time progresses nevertheless since this refers to the * system clocks. * */ @JsonTypeName("time") public class ProgressTime implements Progress { /** * time in millis as returned from {@link System#currentTimeMillis()}. Note, * we do not use RFC 3339 because we need millisecond accuracy. */ private final Date start; /** * duration in millis. we do not use ISO 8601 because we need millisecond * accuracy. */ private final Long duration; /** * * @param d the duration, eg {@link DeadlineTime#getDuration()}. Must be * > 0. * @param start the start Date (unix time in millisecs since 1970). See * {@link System#currentTimeMillis()}. */ @JsonCreator public ProgressTime(@JsonProperty("duration") Long d, @JsonProperty("start") Date start) { this.start = start; duration = (d == null || d <= 0) ? 1 : d; } @Override public Double get(Long currentTimeMs) { long delta = currentTimeMs - start.getTime(); // double should have ~53 digits of precision, and we're computing // deltas here. // 2^53 millis seems plenty for our purposes so no need to use // BigDecimal here. Double ratio = delta / (double) duration; if (ratio > 1d) ratio = 1d; else if (ratio < 0d) ratio = 0d; return ratio; } @Override public boolean isPastDeadline(Long currentTimeMs) { return currentTimeMs > start.getTime() + duration; } /** * * @return time measured in milliseconds, between the start time and * midnight, January 1, 1970 UTCas returned from * {@link System#currentTimeMillis()} * */ public Date getStart() { return start; } /** * * @return duration in milliseconds. */ public Long getDuration() { return duration; } @Override public Date getTerminationTime() { return new Date(start.getTime() + duration); } @Override public String toString() { return "ProgressTime[" + start.getTime() + " , " + duration + "ms]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((duration == null) ? 0 : duration.hashCode()); result = prime * result + ((start == null) ? 0 : start.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ProgressTime other = (ProgressTime) obj; if (duration == null) { if (other.duration != null) return false; } else if (!duration.equals(other.duration)) return false; if (start == null) { if (other.start != null) return false; } else if (!start.equals(other.start)) return false; return true; } }