public bool TryToTimeSpan()

in Elfie/Elfie/Model/Strings/String8.cs [1157:1227]


        public bool TryToTimeSpan(out TimeSpan result)
        {
            const string TimeSpanMinValue = "-10675199.02:48:05.4775808";

            result = TimeSpan.Zero;
            if (this.IsEmpty()) return false;

            // If the TimeSpan is negative, parse the rest and negate
            bool isNegative = this.StartsWith(UTF8.Dash);
            if(isNegative)
            {
                // Handle TimeSpan.MinValue separately since it will overflow as a positive value
                if(this.Length == TimeSpanMinValue.Length && this.Equals(TimeSpanMinValue))
                {
                    result = TimeSpan.MinValue;
                    return true;
                }

                bool succeeded = this.Substring(1).TryToTimeSpan(out result);
                result = -result;
                return succeeded;
            }

            uint days = 0, hours = 0, minutes = 0, seconds = 0, ticks = 0;

            // Find the first colon (hour:minute)
            int hourIndex = this.IndexOf(UTF8.Colon) - 2;

            // If this is a days-only TimeSpan, try to parse it
            if (hourIndex < 0)
            {
                if (!this.TryToUInt(out days)) return false;
            }
            else
            {
                // Use length to infer components which must be present
                bool hasDays = (hourIndex > 0);
                bool hasSeconds = (Length - hourIndex > 5);                 // HH:MMx
                bool hasPartialSeconds = (Length - hourIndex > 8);          // HH:MM:SSx

                // Validate separators
                if (hasDays && this[hourIndex - 1] != UTF8.Period) return false;
                if (hasSeconds && this[hourIndex + 5] != UTF8.Colon) return false;
                if (hasPartialSeconds && this[hourIndex + 8] != UTF8.Period) return false;

                // Parse Days, Hours, Minutes, Seconds
                if (hasDays && !this.Substring(0, hourIndex - 1).TryToUInt(out days)) return false;
                if (!this.Substring(hourIndex, 2).TryToUInt(out hours)) return false;
                if (!this.Substring(hourIndex + 3, 2).TryToUInt(out minutes)) return false;
                if (hasSeconds && !this.Substring(hourIndex + 6, 2).TryToUInt(out seconds)) return false;

                // Parse Partial Seconds and normalize to ticks (0.1s -> 100k ticks, ticks are millionths of a second)
                if (hasPartialSeconds)
                {
                    String8 partialSeconds = this.Substring(hourIndex + 9);
                    if (partialSeconds.Length > 7) return false;
                    if (!partialSeconds.TryToUInt(out ticks)) return false;
                    if (partialSeconds.Length < 7) ticks *= (uint)Math.Pow(10, 7 - partialSeconds.Length);
                }
            }

            // Validate number ranges
            if (days > 10675199) return false;
            if (hours > 23) return false;
            if (minutes > 59) return false;
            if (seconds > 59) return false;

            // Construct the TimeSpan
            result = new TimeSpan((int)days, (int)hours, (int)minutes, (int)seconds).Add(new TimeSpan(ticks));
            return true;
        }