5 // Duco Fijma (duco@lorentz.xs4all.nl)
11 public struct TimeSpan : IComparable {
16 public TimeSpan (long value) { ticks = value; }
17 public TimeSpan (int hours, int minutes, int seconds)
18 : this(0, hours, minutes, seconds, 0) {}
19 public TimeSpan (int days, int hours, int minutes, int seconds)
20 : this(days, hours, minutes, seconds, 0) {}
21 public TimeSpan (int days, int hours, int minutes, int seconds, int milliseconds)
23 ticks = TicksPerDay * days +
24 TicksPerHour * hours +
25 TicksPerMinute * minutes +
26 TicksPerSecond * seconds +
27 TicksPerMillisecond * milliseconds;
32 public static readonly TimeSpan MaxValue = new TimeSpan (long.MaxValue);
33 public static readonly TimeSpan MinValue = new TimeSpan (long.MinValue);
34 public const long TicksPerDay = 864000000000L;
35 public const long TicksPerHour = 36000000000L;
36 public const long TicksPerMillisecond = 10000L;
37 public const long TicksPerMinute = 600000000L;
38 public const long TicksPerSecond = 10000000L;
39 public static readonly TimeSpan Zero = new TimeSpan (0L);
46 return (int) TotalDays;
53 return (int) (ticks % TicksPerDay / TicksPerHour);
57 public int Milliseconds
61 return (int) (ticks % TicksPerSecond / TicksPerMillisecond);
69 return (int) (ticks % TicksPerHour / TicksPerMinute);
77 return (int) (ticks % TicksPerMinute / TicksPerSecond);
89 public double TotalDays
93 return (double) ticks / TicksPerDay;
97 public double TotalHours
101 return (double) ticks / TicksPerHour;
105 public double TotalMilliseconds
109 return (double) ticks / TicksPerMillisecond;
113 public double TotalMinutes
116 return (double) ticks / TicksPerMinute;
120 public double TotalSeconds
123 return (double) ticks / TicksPerSecond;
129 public TimeSpan Add (TimeSpan ts)
132 return new TimeSpan (ticks+ts.Ticks);
136 public static int Compare (TimeSpan t1, TimeSpan t2)
138 if (t1.ticks < t2.ticks) {
141 else if (t1.ticks > t2.ticks) {
149 public int CompareTo (object value)
152 if (value == null ) {
156 if (!(value is TimeSpan)) {
157 throw new ArgumentException("Argument of System.TimeSpan.CompareTo should be a TimeSpan");
160 return Compare(this, (TimeSpan) value);
163 // Overflow issue for Duration is like for Negate.
164 public TimeSpan Duration ()
167 return new TimeSpan (Math.Abs (ticks));
171 // TODO: Consider implementing this version
172 // in terms of Equals(TimeSPan, TimeSpan)
173 public override bool Equals (object value)
175 if (value == null || !(value is TimeSpan)) {
178 return ticks == ((TimeSpan) (value)).ticks;
181 public static new bool Equals(TimeSpan t1, TimeSpan t2)
183 return t1.Equals (t2);
186 // Implementing FromDays -> FromHours -> FromMinutes -> FromSeconds ->
187 // FromMilliseconds as done here is probably not the most efficient
190 public static TimeSpan FromDays (double value)
192 if (Double.IsNaN(value) || Double.IsNegativeInfinity(value)) {
196 if (Double.IsPositiveInfinity(value)) {
200 return new TimeSpan((int) value,0,0,0,0) + FromHours ((value - ((int) value)) * 24);
203 public static TimeSpan FromHours (double value)
205 if (Double.IsNaN(value) || Double.IsNegativeInfinity(value)) {
209 if (Double.IsPositiveInfinity(value)) {
213 return new TimeSpan ((int) value,0,0) + FromMinutes ((value - ((int) value)) * 60);
216 public static TimeSpan FromMinutes(double value)
218 if (Double.IsNaN(value) || Double.IsNegativeInfinity(value)) {
222 if (Double.IsPositiveInfinity(value)) {
226 return new TimeSpan (0,(int) value,0) + FromSeconds((value - ((int) value)) * 60);
229 public static TimeSpan FromSeconds(double value)
231 if (Double.IsNaN(value) || Double.IsNegativeInfinity(value)) {
235 if (Double.IsPositiveInfinity(value)) {
239 return new TimeSpan (0,0,0,(int) value,((int) ((value - ((int) value)) * 1000)));
243 public static TimeSpan FromTicks (long value)
245 return new TimeSpan (value);
248 public override int GetHashCode()
250 return ticks.GetHashCode();
253 // TODO: It makes sense that Negate can throw an overflow
254 // exception (if negating MinValue). Is this specified
256 public TimeSpan Negate()
259 return new TimeSpan(- ticks);
264 public static TimeSpan Parse(string s)
269 public TimeSpan Subtract(TimeSpan ts)
272 return new TimeSpan(ticks - ts.Ticks);
276 public override string ToString()
284 // We need to take absolute values of all components.
285 // Can't handle negative timespans by negating the TimeSpan
286 // as a whole. This would lead to an overflow for the
287 // degenerate case "TimeSpan.MinValue.ToString()".
290 res += Math.Abs(Days) + "." ;
293 res += string.Format("{0:00}:{1:00}:{2:00}", Math.Abs(Hours), Math.Abs(Minutes), Math.Abs(Seconds));
295 int fractional = (int) Math.Abs(ticks % TicksPerSecond);
296 if (fractional != 0) {
297 res += string.Format(".{0:0000000}", fractional);
303 public static TimeSpan operator +(TimeSpan t1, TimeSpan t2)
308 public static bool operator ==(TimeSpan t1, TimeSpan t2)
310 return Compare(t1, t2) == 0;
313 public static bool operator >(TimeSpan t1, TimeSpan t2)
315 return Compare(t1, t2) == 1;
318 public static bool operator >=(TimeSpan t1, TimeSpan t2)
320 return Compare(t1, t2) != -1;
323 public static bool operator !=(TimeSpan t1, TimeSpan t2)
325 return Compare(t1, t2) != 0;
328 public static bool operator <(TimeSpan t1, TimeSpan t2)
330 return Compare(t1, t2) == -1;
333 public static bool operator <=(TimeSpan t1, TimeSpan t2)
335 return Compare(t1, t2) != 1;
338 public static TimeSpan operator -(TimeSpan t1, TimeSpan t2)
340 return t1.Subtract(t2);
343 public static TimeSpan operator -(TimeSpan t)
348 public static TimeSpan operator +(TimeSpan t)