package org.ovirt.engine.core.compat;
import java.io.Serializable;
import java.util.regex.Pattern;
public class TimeSpan implements Comparable<TimeSpan>, Serializable {
private static final long serialVersionUID = -7809305197875724416L;
public static final int MS_PER_SECOND = 1000;
public static final int MS_PER_MINUTE = 60 * 1000;
public static final int MS_PER_HOUR = 60 * 60 * 1000;
public static final int MS_PER_DAY = 24 * 60 * 60 * 1000;
public int Days;
public int Hours;
public int Minutes;
public int Seconds;
public int Milliseconds;
public double TotalDays;
public double TotalHours;
public double TotalMinutes;
public double TotalSeconds;
public long TotalMilliseconds;
public TimeSpan() {
}
public TimeSpan(long milliseconds) {
TotalMilliseconds = milliseconds;
computeProperties();
}
public TimeSpan(int hours, int minutes, int seconds) {
this(0, hours, minutes, seconds, 0);
}
public TimeSpan(int days, int hours, int minutes, int seconds) {
this(days, hours, minutes, seconds, 0);
}
public TimeSpan(int days, int hours, int minutes, int seconds, int milliseconds) {
TotalMilliseconds = milliseconds;
TotalMilliseconds += seconds * MS_PER_SECOND;
TotalMilliseconds += (long)minutes * (long)MS_PER_MINUTE;
TotalMilliseconds += (long)hours * (long)MS_PER_HOUR;
TotalMilliseconds += (long)days * (long)MS_PER_DAY;
computeProperties();
}
public TimeSpan(int[] data) {
this(data[0], data[1], data[2], data[3], data[4]);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Days;
result = prime * result + Hours;
result = prime * result + Milliseconds;
result = prime * result + Minutes;
result = prime * result + Seconds;
long temp;
temp = Double.doubleToLongBits(TotalDays);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(TotalHours);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + (int) (TotalMilliseconds ^ (TotalMilliseconds >>> 32));
temp = Double.doubleToLongBits(TotalMinutes);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(TotalSeconds);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TimeSpan other = (TimeSpan) obj;
if (Days != other.Days) {
return false;
}
if (Hours != other.Hours) {
return false;
}
if (Milliseconds != other.Milliseconds) {
return false;
}
if (Minutes != other.Minutes) {
return false;
}
if (Seconds != other.Seconds) {
return false;
}
if (Double.doubleToLongBits(TotalDays) != Double.doubleToLongBits(other.TotalDays)) {
return false;
}
if (Double.doubleToLongBits(TotalHours) != Double.doubleToLongBits(other.TotalHours)) {
return false;
}
if (TotalMilliseconds != other.TotalMilliseconds) {
return false;
}
if (Double.doubleToLongBits(TotalMinutes) != Double.doubleToLongBits(other.TotalMinutes)) {
return false;
}
if (Double.doubleToLongBits(TotalSeconds) != Double.doubleToLongBits(other.TotalSeconds)) {
return false;
}
return true;
}
protected void computeProperties() {
long remainder = TotalMilliseconds;
// Days
Days = (int) (remainder / MS_PER_DAY);
remainder = remainder % MS_PER_DAY;
// Hours
Hours = (int) (remainder / MS_PER_HOUR);
remainder = remainder % MS_PER_HOUR;
remainder = remainder % MS_PER_DAY;
// Minutes
Minutes = (int) (remainder / MS_PER_MINUTE);
remainder = remainder % MS_PER_MINUTE;
// Minutes
Seconds = (int) (remainder / MS_PER_SECOND);
remainder = remainder % MS_PER_SECOND;
Milliseconds = (int) remainder;
}
// The format for a timespan is:
// [ws][-]{ d | d.hh:mm[:ss[.ff]] | hh:mm[:ss[.ff]] }[ws]
public static TimeSpan parse(String argvalue) {
String cleaned = argvalue.trim();
int multiplier = 1;
if (cleaned.contains("-")) {
multiplier = -1;
cleaned = cleaned.replace("-", "").trim();
}
if (Pattern.matches("[0-9]+", cleaned)) {
int days = Integer.parseInt(cleaned);
return new TimeSpan(days * multiplier, 0, 0, 0);
}
String regex = "[0-9]+.[0-9]{2}:[0-9]{2}(:[0-9]{2}(.[0-9]{2})?)?";
if (Pattern.matches(regex, cleaned)) {
String[] items = cleaned.split("[:.]");
int[] data = new int[5];
for (int x = 0; x < items.length; x++) {
data[x] = Integer.parseInt(items[x]) * multiplier;
}
return new TimeSpan(data);
}
regex = "[0-9]{2}:[0-9]{2}(:[0-9]{2}(.[0-9]{2})?)?";
if (Pattern.matches(regex, cleaned)) {
String[] items = cleaned.split("[:.]");
int[] data = new int[5];
for (int x = 0; x < items.length; x++) {
data[x + 1] = Integer.parseInt(items[x]) * multiplier;
}
return new TimeSpan(data);
}
// If we get to here, it is invalid
throw new IllegalArgumentException("Invalid TimeSpan");
}
@Override
public String toString() {
// Ok to use String.format directly since GWT does not use TimeSpan from ui override package
return String.format("%s%d.%02d:%02d:%02d.%03d",
(TotalMilliseconds < 0) ? "-" : "",
Days, Hours, Minutes, Seconds, Milliseconds);
}
public static TimeSpan tryParse(String string) {
try {
return TimeSpan.parse(string);
} catch (IllegalArgumentException e) {
// eat it, return null
return null;
}
}
@Override
public int compareTo(TimeSpan o) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException();
}
}