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 += minutes * MS_PER_MINUTE; TotalMilliseconds += hours * MS_PER_HOUR; TotalMilliseconds += days * 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 CompatException("Invalid TimeSpan"); } @Override public String toString() { String prefix = ""; if (TotalMilliseconds < 0) { prefix = "-"; } return StringFormat.format("%s%d.%02d:%02d:%02d.%03d", prefix, Days, Hours, Minutes, Seconds, Milliseconds); } public static boolean TryParse(String string, RefObject<TimeSpan> ref) { boolean returnValue = false; try { TimeSpan result = TimeSpan.Parse(string); returnValue = true; ref.argvalue = result; } catch (CompatException e) { // eat it, return false } return returnValue; } @Override public int compareTo(TimeSpan o) { // TODO Auto-generated method stub throw new NotImplementedException(); } }