Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / clr / src / BCL / System / TimeSpan.cs / 1 / TimeSpan.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== namespace System { using System.Text; using System; // TimeSpan represents a duration of time. A TimeSpan can be negative // or positive. // // TimeSpan is internally represented as a number of milliseconds. While // this maps well into units of time such as hours and days, any // periods longer than that aren't representable in a nice fashion. // For instance, a month can be between 28 and 31 days, while a year // can contain 365 or 364 days. A decade can have between 1 and 3 leapyears, // depending on when you map the TimeSpan into the calendar. This is why // we do not provide Years() or Months(). // [System.Runtime.InteropServices.ComVisible(true)] [Serializable] public struct TimeSpan : IComparable #if GENERICS_WORK , IComparable, IEquatable #endif { public const long TicksPerMillisecond = 10000; private const double MillisecondsPerTick = 1.0 / TicksPerMillisecond; public const long TicksPerSecond = TicksPerMillisecond * 1000; private const double SecondsPerTick = 1.0 / TicksPerSecond; public const long TicksPerMinute = TicksPerSecond * 60; private const double MinutesPerTick = 1.0 / TicksPerMinute; public const long TicksPerHour = TicksPerMinute * 60; private const double HoursPerTick = 1.0 / TicksPerHour; public const long TicksPerDay = TicksPerHour * 24; private const double DaysPerTick = 1.0 / TicksPerDay; private const int MillisPerSecond = 1000; private const int MillisPerMinute = MillisPerSecond * 60; private const int MillisPerHour = MillisPerMinute * 60; private const int MillisPerDay = MillisPerHour * 24; private const long MaxSeconds = Int64.MaxValue / TicksPerSecond; private const long MinSeconds = Int64.MinValue / TicksPerSecond; private const long MaxMilliSeconds = Int64.MaxValue / TicksPerMillisecond; private const long MinMilliSeconds = Int64.MinValue / TicksPerMillisecond; public static readonly TimeSpan Zero = new TimeSpan(0); public static readonly TimeSpan MaxValue = new TimeSpan(Int64.MaxValue); public static readonly TimeSpan MinValue = new TimeSpan(Int64.MinValue); // internal so that DateTime doesn't have to call an extra get // method for some arithmetic operations. internal long _ticks; //public TimeSpan() { // _ticks = 0; //} public TimeSpan(long ticks) { this._ticks = ticks; } public TimeSpan(int hours, int minutes, int seconds) { _ticks = TimeToTicks(hours, minutes, seconds); } 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) { Int64 totalMilliSeconds = ((Int64)days * 3600 * 24 + (Int64)hours * 3600 + (Int64)minutes * 60 + seconds) * 1000 + milliseconds; if (totalMilliSeconds > MaxMilliSeconds || totalMilliSeconds < MinMilliSeconds) throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong")); _ticks = (long)totalMilliSeconds * TicksPerMillisecond; } public long Ticks { get { return _ticks; } } public int Days { get { return (int)(_ticks / TicksPerDay); } } public int Hours { get { return (int)((_ticks / TicksPerHour) % 24); } } public int Milliseconds { get { return (int)((_ticks / TicksPerMillisecond) % 1000); } } public int Minutes { get { return (int)((_ticks / TicksPerMinute) % 60); } } public int Seconds { get { return (int)((_ticks / TicksPerSecond) % 60); } } public double TotalDays { get { return ((double)_ticks) * DaysPerTick; } } public double TotalHours { get { return (double)_ticks * HoursPerTick; } } public double TotalMilliseconds { get { double temp = (double)_ticks * MillisecondsPerTick; if (temp > MaxMilliSeconds) return (double)MaxMilliSeconds; if (temp < MinMilliSeconds) return (double)MinMilliSeconds; return temp; } } public double TotalMinutes { get { return (double)_ticks * MinutesPerTick; } } public double TotalSeconds { get { return (double)_ticks * SecondsPerTick; } } public TimeSpan Add(TimeSpan ts) { long result = _ticks + ts._ticks; // Overflow if signs of operands was identical and result's // sign was opposite. // >> 63 gives the sign bit (either 64 1's or 64 0's). if ((_ticks >> 63 == ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); return new TimeSpan(result); } // Compares two TimeSpan values, returning an integer that indicates their // relationship. // public static int Compare(TimeSpan t1, TimeSpan t2) { if (t1._ticks > t2._ticks) return 1; if (t1._ticks < t2._ticks) return -1; return 0; } // Returns a value less than zero if this object public int CompareTo(Object value) { if (value == null) return 1; if (!(value is TimeSpan)) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeTimeSpan")); long t = ((TimeSpan)value)._ticks; if (_ticks > t) return 1; if (_ticks < t) return -1; return 0; } #if GENERICS_WORK public int CompareTo(TimeSpan value) { long t = value._ticks; if (_ticks > t) return 1; if (_ticks < t) return -1; return 0; } #endif public static TimeSpan FromDays(double value) { return Interval(value, MillisPerDay); } public TimeSpan Duration() { if (_ticks==TimeSpan.MinValue._ticks) throw new OverflowException(Environment.GetResourceString("Overflow_Duration")); return new TimeSpan(_ticks >= 0? _ticks: -_ticks); } public override bool Equals(Object value) { if (value is TimeSpan) { return _ticks == ((TimeSpan)value)._ticks; } return false; } public bool Equals(TimeSpan obj) { return _ticks == obj._ticks; } public static bool Equals(TimeSpan t1, TimeSpan t2) { return t1._ticks == t2._ticks; } public override int GetHashCode() { return (int)_ticks ^ (int)(_ticks >> 32); } public static TimeSpan FromHours(double value) { return Interval(value, MillisPerHour); } private static TimeSpan Interval(double value, int scale) { if (Double.IsNaN(value)) throw new ArgumentException(Environment.GetResourceString("Arg_CannotBeNaN")); double tmp = value * scale; double millis = tmp + (value >= 0? 0.5: -0.5); if ((millis > Int64.MaxValue / TicksPerMillisecond) || (millis < Int64.MinValue / TicksPerMillisecond)) throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); return new TimeSpan((long)millis * TicksPerMillisecond); } public static TimeSpan FromMilliseconds(double value) { return Interval(value, 1); } public static TimeSpan FromMinutes(double value) { return Interval(value, MillisPerMinute); } public TimeSpan Negate() { if (_ticks==TimeSpan.MinValue._ticks) throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum")); return new TimeSpan(-_ticks); } // Constructs a TimeSpan from a string. Leading and trailing white // space characters are allowed. // public static TimeSpan Parse(String s) { return new TimeSpan(new StringParser().Parse(s)); } public static Boolean TryParse(String s, out TimeSpan result) { long longResult; if (new StringParser().TryParse(s, out longResult)) { result = new TimeSpan(longResult); return true; } else { result = TimeSpan.Zero; return false; } } public static TimeSpan FromSeconds(double value) { return Interval(value, MillisPerSecond); } public TimeSpan Subtract(TimeSpan ts) { long result = _ticks - ts._ticks; // Overflow if signs of operands was different and result's // sign was opposite from the first argument's sign. // >> 63 gives the sign bit (either 64 1's or 64 0's). if ((_ticks >> 63 != ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); return new TimeSpan(result); } public static TimeSpan FromTicks(long value) { return new TimeSpan(value); } internal static long TimeToTicks(int hour, int minute, int second) { // totalSeconds is bounded by 2^31 * 2^12 + 2^31 * 2^8 + 2^31, // which is less than 2^44, meaning we won't overflow totalSeconds. long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second; if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds) throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong")); return totalSeconds * TicksPerSecond; } private String IntToString(int n, int digits) { return ParseNumbers.IntToString(n, 10, digits, '0', 0); } public override String ToString() { StringBuilder sb = new StringBuilder(); int day = (int)(_ticks / TicksPerDay); long time = _ticks % TicksPerDay; if (_ticks < 0) { sb.Append("-"); day = -day; time = -time; } if (day != 0) { sb.Append(day); sb.Append("."); } sb.Append(IntToString((int)(time / TicksPerHour % 24), 2)); sb.Append(":"); sb.Append(IntToString((int)(time / TicksPerMinute % 60), 2)); sb.Append(":"); sb.Append(IntToString((int)(time / TicksPerSecond % 60), 2)); int t = (int)(time % TicksPerSecond); if (t != 0) { sb.Append("."); sb.Append(IntToString(t, 7)); } return sb.ToString(); } public static TimeSpan operator -(TimeSpan t) { if (t._ticks==TimeSpan.MinValue._ticks) throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum")); return new TimeSpan(-t._ticks); } public static TimeSpan operator -(TimeSpan t1, TimeSpan t2) { return t1.Subtract(t2); } public static TimeSpan operator +(TimeSpan t) { return t; } public static TimeSpan operator +(TimeSpan t1, TimeSpan t2) { return t1.Add(t2); } public static bool operator ==(TimeSpan t1, TimeSpan t2) { return t1._ticks == t2._ticks; } public static bool operator !=(TimeSpan t1, TimeSpan t2) { return t1._ticks != t2._ticks; } public static bool operator <(TimeSpan t1, TimeSpan t2) { return t1._ticks < t2._ticks; } public static bool operator <=(TimeSpan t1, TimeSpan t2) { return t1._ticks <= t2._ticks; } public static bool operator >(TimeSpan t1, TimeSpan t2) { return t1._ticks > t2._ticks; } public static bool operator >=(TimeSpan t1, TimeSpan t2) { return t1._ticks >= t2._ticks; } private struct StringParser { private enum ParseError { Format = 1, Overflow = 2, OverflowHoursMinutesSeconds = 3, ArgumentNull = 4, } private String str; private char ch; private int pos; private int len; private ParseError error; internal void NextChar() { if (pos < len) pos++; ch = pos < len? str[pos]: (char) 0; } internal char NextNonDigit() { int i = pos; while (i < len) { char ch = str[i]; if (ch < '0' || ch > '9') return ch; i++; } return (char) 0; } internal long Parse(String s) { long value; if (TryParse(s, out value)) { return value; } else { switch (error) { case ParseError.ArgumentNull: throw new ArgumentNullException("s"); case ParseError.Format: throw new FormatException(Environment.GetResourceString("Format_InvalidString")); case ParseError.Overflow: throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); case ParseError.OverflowHoursMinutesSeconds: throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanElementTooLarge")); default: BCLDebug.Assert(false, "Unknown error: " + error.ToString()); return 0; } } } internal bool TryParse(String s, out long value) { value = 0; if (s == null) { error = ParseError.ArgumentNull; return false; } str = s; len = s.Length; pos = -1; NextChar(); SkipBlanks(); bool negative = false; if (ch == '-') { negative = true; NextChar(); } long time; if (NextNonDigit() == ':') { if (!ParseTime(out time)) { return false; }; } else { int days; if (!ParseInt((int)(0x7FFFFFFFFFFFFFFFL / TicksPerDay), out days)) { return false; } time = days * TicksPerDay; if (ch == '.') { NextChar(); long remainingTime; if (!ParseTime(out remainingTime)) { return false; }; time += remainingTime; } } if (negative) { time = -time; // Allow -0 as well if (time > 0) { error = ParseError.Overflow; return false; } } else { if (time < 0) { error = ParseError.Overflow; return false; } } SkipBlanks(); if (pos < len) { error = ParseError.Format; return false; } value = time; return true; } internal bool ParseInt(int max, out int i) { i = 0; int p = pos; while (ch >= '0' && ch <= '9') { if ((i & 0xF0000000) != 0) { error = ParseError.Overflow; return false; } i = i * 10 + ch - '0'; if (i < 0) { error = ParseError.Overflow; return false; } NextChar(); } if (p == pos) { error = ParseError.Format; return false; } if (i > max) { error = ParseError.Overflow; return false; } return true; } internal bool ParseTime(out long time) { time = 0; int unit; if (!ParseInt(23, out unit)) { if (error == ParseError.Overflow) { error = ParseError.OverflowHoursMinutesSeconds; } return false; } time = unit * TicksPerHour; if (ch != ':') { error = ParseError.Format; return false; } NextChar(); if (!ParseInt(59, out unit)) { if (error == ParseError.Overflow) { error = ParseError.OverflowHoursMinutesSeconds; } return false; } time += unit * TicksPerMinute; if (ch == ':') { NextChar(); // allow seconds with the leading zero if (ch != '.') { if (!ParseInt(59, out unit)) { if (error == ParseError.Overflow) { error = ParseError.OverflowHoursMinutesSeconds; } return false; } time += unit * TicksPerSecond; } if (ch == '.') { NextChar(); int f = (int)TicksPerSecond; while (f > 1 && ch >= '0' && ch <= '9') { f /= 10; time += (ch - '0') * f; NextChar(); } } } return true; } internal void SkipBlanks() { while (ch == ' ' || ch == '\t') NextChar(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== namespace System { using System.Text; using System; // TimeSpan represents a duration of time. A TimeSpan can be negative // or positive. // // TimeSpan is internally represented as a number of milliseconds. While // this maps well into units of time such as hours and days, any // periods longer than that aren't representable in a nice fashion. // For instance, a month can be between 28 and 31 days, while a year // can contain 365 or 364 days. A decade can have between 1 and 3 leapyears, // depending on when you map the TimeSpan into the calendar. This is why // we do not provide Years() or Months(). // [System.Runtime.InteropServices.ComVisible(true)] [Serializable] public struct TimeSpan : IComparable #if GENERICS_WORK , IComparable , IEquatable #endif { public const long TicksPerMillisecond = 10000; private const double MillisecondsPerTick = 1.0 / TicksPerMillisecond; public const long TicksPerSecond = TicksPerMillisecond * 1000; private const double SecondsPerTick = 1.0 / TicksPerSecond; public const long TicksPerMinute = TicksPerSecond * 60; private const double MinutesPerTick = 1.0 / TicksPerMinute; public const long TicksPerHour = TicksPerMinute * 60; private const double HoursPerTick = 1.0 / TicksPerHour; public const long TicksPerDay = TicksPerHour * 24; private const double DaysPerTick = 1.0 / TicksPerDay; private const int MillisPerSecond = 1000; private const int MillisPerMinute = MillisPerSecond * 60; private const int MillisPerHour = MillisPerMinute * 60; private const int MillisPerDay = MillisPerHour * 24; private const long MaxSeconds = Int64.MaxValue / TicksPerSecond; private const long MinSeconds = Int64.MinValue / TicksPerSecond; private const long MaxMilliSeconds = Int64.MaxValue / TicksPerMillisecond; private const long MinMilliSeconds = Int64.MinValue / TicksPerMillisecond; public static readonly TimeSpan Zero = new TimeSpan(0); public static readonly TimeSpan MaxValue = new TimeSpan(Int64.MaxValue); public static readonly TimeSpan MinValue = new TimeSpan(Int64.MinValue); // internal so that DateTime doesn't have to call an extra get // method for some arithmetic operations. internal long _ticks; //public TimeSpan() { // _ticks = 0; //} public TimeSpan(long ticks) { this._ticks = ticks; } public TimeSpan(int hours, int minutes, int seconds) { _ticks = TimeToTicks(hours, minutes, seconds); } 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) { Int64 totalMilliSeconds = ((Int64)days * 3600 * 24 + (Int64)hours * 3600 + (Int64)minutes * 60 + seconds) * 1000 + milliseconds; if (totalMilliSeconds > MaxMilliSeconds || totalMilliSeconds < MinMilliSeconds) throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong")); _ticks = (long)totalMilliSeconds * TicksPerMillisecond; } public long Ticks { get { return _ticks; } } public int Days { get { return (int)(_ticks / TicksPerDay); } } public int Hours { get { return (int)((_ticks / TicksPerHour) % 24); } } public int Milliseconds { get { return (int)((_ticks / TicksPerMillisecond) % 1000); } } public int Minutes { get { return (int)((_ticks / TicksPerMinute) % 60); } } public int Seconds { get { return (int)((_ticks / TicksPerSecond) % 60); } } public double TotalDays { get { return ((double)_ticks) * DaysPerTick; } } public double TotalHours { get { return (double)_ticks * HoursPerTick; } } public double TotalMilliseconds { get { double temp = (double)_ticks * MillisecondsPerTick; if (temp > MaxMilliSeconds) return (double)MaxMilliSeconds; if (temp < MinMilliSeconds) return (double)MinMilliSeconds; return temp; } } public double TotalMinutes { get { return (double)_ticks * MinutesPerTick; } } public double TotalSeconds { get { return (double)_ticks * SecondsPerTick; } } public TimeSpan Add(TimeSpan ts) { long result = _ticks + ts._ticks; // Overflow if signs of operands was identical and result's // sign was opposite. // >> 63 gives the sign bit (either 64 1's or 64 0's). if ((_ticks >> 63 == ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); return new TimeSpan(result); } // Compares two TimeSpan values, returning an integer that indicates their // relationship. // public static int Compare(TimeSpan t1, TimeSpan t2) { if (t1._ticks > t2._ticks) return 1; if (t1._ticks < t2._ticks) return -1; return 0; } // Returns a value less than zero if this object public int CompareTo(Object value) { if (value == null) return 1; if (!(value is TimeSpan)) throw new ArgumentException(Environment.GetResourceString("Arg_MustBeTimeSpan")); long t = ((TimeSpan)value)._ticks; if (_ticks > t) return 1; if (_ticks < t) return -1; return 0; } #if GENERICS_WORK public int CompareTo(TimeSpan value) { long t = value._ticks; if (_ticks > t) return 1; if (_ticks < t) return -1; return 0; } #endif public static TimeSpan FromDays(double value) { return Interval(value, MillisPerDay); } public TimeSpan Duration() { if (_ticks==TimeSpan.MinValue._ticks) throw new OverflowException(Environment.GetResourceString("Overflow_Duration")); return new TimeSpan(_ticks >= 0? _ticks: -_ticks); } public override bool Equals(Object value) { if (value is TimeSpan) { return _ticks == ((TimeSpan)value)._ticks; } return false; } public bool Equals(TimeSpan obj) { return _ticks == obj._ticks; } public static bool Equals(TimeSpan t1, TimeSpan t2) { return t1._ticks == t2._ticks; } public override int GetHashCode() { return (int)_ticks ^ (int)(_ticks >> 32); } public static TimeSpan FromHours(double value) { return Interval(value, MillisPerHour); } private static TimeSpan Interval(double value, int scale) { if (Double.IsNaN(value)) throw new ArgumentException(Environment.GetResourceString("Arg_CannotBeNaN")); double tmp = value * scale; double millis = tmp + (value >= 0? 0.5: -0.5); if ((millis > Int64.MaxValue / TicksPerMillisecond) || (millis < Int64.MinValue / TicksPerMillisecond)) throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); return new TimeSpan((long)millis * TicksPerMillisecond); } public static TimeSpan FromMilliseconds(double value) { return Interval(value, 1); } public static TimeSpan FromMinutes(double value) { return Interval(value, MillisPerMinute); } public TimeSpan Negate() { if (_ticks==TimeSpan.MinValue._ticks) throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum")); return new TimeSpan(-_ticks); } // Constructs a TimeSpan from a string. Leading and trailing white // space characters are allowed. // public static TimeSpan Parse(String s) { return new TimeSpan(new StringParser().Parse(s)); } public static Boolean TryParse(String s, out TimeSpan result) { long longResult; if (new StringParser().TryParse(s, out longResult)) { result = new TimeSpan(longResult); return true; } else { result = TimeSpan.Zero; return false; } } public static TimeSpan FromSeconds(double value) { return Interval(value, MillisPerSecond); } public TimeSpan Subtract(TimeSpan ts) { long result = _ticks - ts._ticks; // Overflow if signs of operands was different and result's // sign was opposite from the first argument's sign. // >> 63 gives the sign bit (either 64 1's or 64 0's). if ((_ticks >> 63 != ts._ticks >> 63) && (_ticks >> 63 != result >> 63)) throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); return new TimeSpan(result); } public static TimeSpan FromTicks(long value) { return new TimeSpan(value); } internal static long TimeToTicks(int hour, int minute, int second) { // totalSeconds is bounded by 2^31 * 2^12 + 2^31 * 2^8 + 2^31, // which is less than 2^44, meaning we won't overflow totalSeconds. long totalSeconds = (long)hour * 3600 + (long)minute * 60 + (long)second; if (totalSeconds > MaxSeconds || totalSeconds < MinSeconds) throw new ArgumentOutOfRangeException(null, Environment.GetResourceString("Overflow_TimeSpanTooLong")); return totalSeconds * TicksPerSecond; } private String IntToString(int n, int digits) { return ParseNumbers.IntToString(n, 10, digits, '0', 0); } public override String ToString() { StringBuilder sb = new StringBuilder(); int day = (int)(_ticks / TicksPerDay); long time = _ticks % TicksPerDay; if (_ticks < 0) { sb.Append("-"); day = -day; time = -time; } if (day != 0) { sb.Append(day); sb.Append("."); } sb.Append(IntToString((int)(time / TicksPerHour % 24), 2)); sb.Append(":"); sb.Append(IntToString((int)(time / TicksPerMinute % 60), 2)); sb.Append(":"); sb.Append(IntToString((int)(time / TicksPerSecond % 60), 2)); int t = (int)(time % TicksPerSecond); if (t != 0) { sb.Append("."); sb.Append(IntToString(t, 7)); } return sb.ToString(); } public static TimeSpan operator -(TimeSpan t) { if (t._ticks==TimeSpan.MinValue._ticks) throw new OverflowException(Environment.GetResourceString("Overflow_NegateTwosCompNum")); return new TimeSpan(-t._ticks); } public static TimeSpan operator -(TimeSpan t1, TimeSpan t2) { return t1.Subtract(t2); } public static TimeSpan operator +(TimeSpan t) { return t; } public static TimeSpan operator +(TimeSpan t1, TimeSpan t2) { return t1.Add(t2); } public static bool operator ==(TimeSpan t1, TimeSpan t2) { return t1._ticks == t2._ticks; } public static bool operator !=(TimeSpan t1, TimeSpan t2) { return t1._ticks != t2._ticks; } public static bool operator <(TimeSpan t1, TimeSpan t2) { return t1._ticks < t2._ticks; } public static bool operator <=(TimeSpan t1, TimeSpan t2) { return t1._ticks <= t2._ticks; } public static bool operator >(TimeSpan t1, TimeSpan t2) { return t1._ticks > t2._ticks; } public static bool operator >=(TimeSpan t1, TimeSpan t2) { return t1._ticks >= t2._ticks; } private struct StringParser { private enum ParseError { Format = 1, Overflow = 2, OverflowHoursMinutesSeconds = 3, ArgumentNull = 4, } private String str; private char ch; private int pos; private int len; private ParseError error; internal void NextChar() { if (pos < len) pos++; ch = pos < len? str[pos]: (char) 0; } internal char NextNonDigit() { int i = pos; while (i < len) { char ch = str[i]; if (ch < '0' || ch > '9') return ch; i++; } return (char) 0; } internal long Parse(String s) { long value; if (TryParse(s, out value)) { return value; } else { switch (error) { case ParseError.ArgumentNull: throw new ArgumentNullException("s"); case ParseError.Format: throw new FormatException(Environment.GetResourceString("Format_InvalidString")); case ParseError.Overflow: throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanTooLong")); case ParseError.OverflowHoursMinutesSeconds: throw new OverflowException(Environment.GetResourceString("Overflow_TimeSpanElementTooLarge")); default: BCLDebug.Assert(false, "Unknown error: " + error.ToString()); return 0; } } } internal bool TryParse(String s, out long value) { value = 0; if (s == null) { error = ParseError.ArgumentNull; return false; } str = s; len = s.Length; pos = -1; NextChar(); SkipBlanks(); bool negative = false; if (ch == '-') { negative = true; NextChar(); } long time; if (NextNonDigit() == ':') { if (!ParseTime(out time)) { return false; }; } else { int days; if (!ParseInt((int)(0x7FFFFFFFFFFFFFFFL / TicksPerDay), out days)) { return false; } time = days * TicksPerDay; if (ch == '.') { NextChar(); long remainingTime; if (!ParseTime(out remainingTime)) { return false; }; time += remainingTime; } } if (negative) { time = -time; // Allow -0 as well if (time > 0) { error = ParseError.Overflow; return false; } } else { if (time < 0) { error = ParseError.Overflow; return false; } } SkipBlanks(); if (pos < len) { error = ParseError.Format; return false; } value = time; return true; } internal bool ParseInt(int max, out int i) { i = 0; int p = pos; while (ch >= '0' && ch <= '9') { if ((i & 0xF0000000) != 0) { error = ParseError.Overflow; return false; } i = i * 10 + ch - '0'; if (i < 0) { error = ParseError.Overflow; return false; } NextChar(); } if (p == pos) { error = ParseError.Format; return false; } if (i > max) { error = ParseError.Overflow; return false; } return true; } internal bool ParseTime(out long time) { time = 0; int unit; if (!ParseInt(23, out unit)) { if (error == ParseError.Overflow) { error = ParseError.OverflowHoursMinutesSeconds; } return false; } time = unit * TicksPerHour; if (ch != ':') { error = ParseError.Format; return false; } NextChar(); if (!ParseInt(59, out unit)) { if (error == ParseError.Overflow) { error = ParseError.OverflowHoursMinutesSeconds; } return false; } time += unit * TicksPerMinute; if (ch == ':') { NextChar(); // allow seconds with the leading zero if (ch != '.') { if (!ParseInt(59, out unit)) { if (error == ParseError.Overflow) { error = ParseError.OverflowHoursMinutesSeconds; } return false; } time += unit * TicksPerSecond; } if (ch == '.') { NextChar(); int f = (int)TicksPerSecond; while (f > 1 && ch >= '0' && ch <= '9') { f /= 10; time += (ch - '0') * f; NextChar(); } } } return true; } internal void SkipBlanks() { while (ch == ' ' || ch == '\t') NextChar(); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SqlExpander.cs
- StsCommunicationException.cs
- GcHandle.cs
- DataRelationPropertyDescriptor.cs
- ToolBarTray.cs
- SerializationSectionGroup.cs
- WindowsListViewScroll.cs
- _SslState.cs
- TypeBuilderInstantiation.cs
- GreenMethods.cs
- SmiEventSink_DeferedProcessing.cs
- XPathAxisIterator.cs
- FontStyle.cs
- CompoundFileStorageReference.cs
- querybuilder.cs
- RelationshipType.cs
- SchemaNotation.cs
- DiscoveryOperationContext.cs
- DesignTimeVisibleAttribute.cs
- GeometryDrawing.cs
- CombinedHttpChannel.cs
- MemoryStream.cs
- MaskedTextBoxDesigner.cs
- StylusEditingBehavior.cs
- UTF32Encoding.cs
- ScriptReference.cs
- GridLengthConverter.cs
- EventMappingSettings.cs
- UnionExpr.cs
- DataControlLinkButton.cs
- ExpressionEditorAttribute.cs
- TransformerInfoCollection.cs
- RequestQueryProcessor.cs
- BamlStream.cs
- HotSpot.cs
- URI.cs
- ObjectDataSourceDisposingEventArgs.cs
- Signature.cs
- SqlDataSourceStatusEventArgs.cs
- ForwardPositionQuery.cs
- EmptyQuery.cs
- AnimatedTypeHelpers.cs
- TakeOrSkipQueryOperator.cs
- RemoteArgument.cs
- RbTree.cs
- DataColumnCollection.cs
- TypeHelpers.cs
- Columns.cs
- DeferredReference.cs
- hresults.cs
- NextPreviousPagerField.cs
- GiveFeedbackEvent.cs
- PropertyGrid.cs
- GiveFeedbackEvent.cs
- GeneralTransformCollection.cs
- LoginDesignerUtil.cs
- listitem.cs
- SiteOfOriginContainer.cs
- TemplateAction.cs
- RemoteDebugger.cs
- ChangeTracker.cs
- UmAlQuraCalendar.cs
- httpapplicationstate.cs
- ListBase.cs
- RoleGroupCollection.cs
- SkinBuilder.cs
- RoleServiceManager.cs
- Calendar.cs
- DataGridViewTopRowAccessibleObject.cs
- AdRotator.cs
- ListBoxAutomationPeer.cs
- DataTableExtensions.cs
- TextEditorContextMenu.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- PersonalizationProvider.cs
- UniqueIdentifierService.cs
- _NetRes.cs
- MeasureData.cs
- NewArrayExpression.cs
- ProtocolsConfiguration.cs
- ExpandCollapsePattern.cs
- xamlnodes.cs
- TypeConverterHelper.cs
- ContextMenu.cs
- JpegBitmapEncoder.cs
- OutOfMemoryException.cs
- Stacktrace.cs
- StrokeCollectionDefaultValueFactory.cs
- QueryParameter.cs
- RadioButton.cs
- HierarchicalDataTemplate.cs
- GACIdentityPermission.cs
- WindowsIPAddress.cs
- Transform3D.cs
- WebPartConnectionCollection.cs
- TextParentUndoUnit.cs
- Privilege.cs
- WebPartDisplayModeEventArgs.cs
- InstanceNameConverter.cs
- SqlDataAdapter.cs