package com.momega.spacesimulator.utils;
import java.util.Calendar;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.DateTimeUtils;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.joda.time.format.PeriodFormatter;
import org.joda.time.format.PeriodFormatterBuilder;
import org.springframework.util.Assert;
import com.momega.spacesimulator.model.PositionProvider;
import com.momega.spacesimulator.model.TimeInterval;
import com.momega.spacesimulator.model.Timestamp;
/**
* Set of the function working with time
* Created by martin on 6/7/14.
*/
public class TimeUtils {
/**
* Julian Day 2000 timestamp instance
*/
public static final Timestamp JD2000 = fromJulianDay(2000.0);
public static DateTimeFormatter UTC_FORMATTER = ISODateTimeFormat.dateTime();
private static PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
.appendDays()
.appendSuffix(" d")
.appendSeparator(" ")
.appendHours()
.appendSuffix(" h")
.appendSeparator(" ")
.appendMinutes()
.appendSuffix(" m")
.appendSeparator(" ")
.appendSeconds()
.appendSuffix(" s")
.toFormatter();
/**
* Creates the time from julian day
* @param julianDay julian day as double value
* @return new instance of the time
*/
public static Timestamp fromJulianDay(double julianDay) {
Timestamp time = new Timestamp();
time.setValue(DateTimeUtils.fromJulianDay(julianDay) / DateTimeConstants.MILLIS_PER_SECOND);
return time;
}
/**
* Creates the timestamp
* @param seconds
* @return
*/
public static Timestamp fromSeconds(double seconds) {
Timestamp time = new Timestamp();
time.setValue(seconds);
return time;
}
/**
* Creates the timestamp object based on the calendar instance
* @param calendar the JDK calendar instance
* @return the new timestamp instance
*/
public static Timestamp fromCalendar(Calendar calendar) {
Assert.notNull(calendar);
long t = calendar.getTimeInMillis();
return fromSeconds( t / DateTimeConstants.MILLIS_PER_SECOND);
}
/**
* Creates the time
* @param datetime datetime
* @return new instance of the time
*/
public static Timestamp fromDateTime(DateTime datetime) {
Timestamp time = new Timestamp();
time.setValue(datetime.getMillis() / DateTimeConstants.MILLIS_PER_SECOND);
return time;
}
/**
* Converts the timestamp to JODA date time
* @param timestamp the timestamp instance
* @return the instance of the JODA time
*/
public static DateTime toDateTime(Timestamp timestamp) {
return new DateTime(toLinuxTime(timestamp));
}
public static long toLinuxTime(Timestamp timestamp) {
long t = Double.valueOf(timestamp.getValue() * DateTimeConstants.MILLIS_PER_SECOND).longValue();
return t;
}
public static Calendar toCalendar(Timestamp timestamp) {
long t = toLinuxTime(timestamp);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(t);
return calendar;
}
public static double getDuration(TimeInterval timeInterval) {
return timeInterval.getEndTime().subtract(timeInterval.getStartTime());
}
public static boolean isTimestampInInterval(Timestamp timestamp, TimeInterval interval) {
Assert.notNull(timestamp);
Assert.notNull(interval);
Assert.notNull(interval.getStartTime());
Assert.notNull(interval.getEndTime());
return (interval.getStartTime().compareTo(timestamp) <=0) &&
(interval.getEndTime().compareTo(timestamp) >= 0);
}
public static boolean isIntervalInFuture(Timestamp timestamp, TimeInterval interval) {
Assert.notNull(timestamp);
Assert.notNull(interval);
Assert.notNull(interval.getStartTime());
return interval.getStartTime().compareTo(timestamp) > 0;
}
public static boolean isIntervalInPast(Timestamp timestamp, TimeInterval interval) {
Assert.notNull(timestamp);
Assert.notNull(interval);
Assert.notNull(interval.getEndTime());
return interval.getEndTime().compareTo(timestamp) < 0;
}
public static String timeAsString(Timestamp timestamp) {
return UTC_FORMATTER.print(TimeUtils.toDateTime(timestamp));
}
public static String periodAsString(PositionProvider positionProvider, Timestamp time) {
double period = getETA(positionProvider, time);
if (period>DateTimeConstants.SECONDS_PER_DAY) {
return timeAsString(positionProvider.getTimestamp());
}
long duration = Double.valueOf(period * DateTimeConstants.MILLIS_PER_SECOND).longValue();
Period p = new Period(duration);
return periodFormatter.print(p);
}
/**
* Returns ETA time in seconds between current time and planned time of the orbital point
* @return the ETA in seconds
* @param positionProvider position provider
* @param time the current time
*/
private static double getETA(PositionProvider positionProvider, Timestamp time) {
Timestamp future = positionProvider.getTimestamp();
return future.subtract(time);
}
}