Loading src/VideoSlice.Cli/SimpleTimeSpanExpress.cs +100 −57 Original line number Diff line number Diff line using System.Text; using System; namespace VideoSlice.Cli; Loading @@ -11,25 +11,37 @@ public static class SimpleTimeSpanExpress /// <returns>时间表达式</returns> public static string ToString(TimeSpan timeSpan) { var days = timeSpan.Days; var hours = timeSpan.Hours; var minutes = timeSpan.Minutes; var seconds = timeSpan.Seconds; var milliseconds = timeSpan.Milliseconds; var microseconds = timeSpan.Microseconds; var len = GetStringLengthFast(timeSpan.Days) + 1 + GetStringLengthFast(timeSpan.Hours) + 1 + GetStringLengthFast(timeSpan.Minutes) + 1 + GetStringLengthFast(timeSpan.Seconds) + 1 + GetStringLengthFast(timeSpan.Milliseconds) + 2 + GetStringLengthFast(timeSpan.Microseconds) + 2 + 4; var sb = new StringBuilder(len); Append(timeSpan.Days, "d", sb); Append(timeSpan.Hours, "h", sb); Append(timeSpan.Minutes, "m", sb); Append(timeSpan.Seconds, "s", sb); Append(timeSpan.Milliseconds, "ms", sb); Append(timeSpan.Microseconds, "us", sb); return sb.ToString(); GetStringLengthFast(days) + 1 + GetStringLengthFast(hours) + 1 + GetStringLengthFast(minutes) + 1 + GetStringLengthFast(seconds) + 1; if (milliseconds != 0) len += GetStringLengthFast(milliseconds) + 2; if (microseconds != 0) len += GetStringLengthFast(microseconds) + 2; return string.Create(len, timeSpan, static (span, ts) => { var pos = span.Length; if (ts.Microseconds != 0) AppendFromEnd(span, ref pos, ts.Microseconds, "us"); if (ts.Milliseconds != 0) AppendFromEnd(span, ref pos, ts.Milliseconds, "ms"); AppendFromEnd(span, ref pos, ts.Seconds, "s"); AppendFromEnd(span, ref pos, ts.Minutes, "m"); AppendFromEnd(span, ref pos, ts.Hours, "h"); AppendFromEnd(span, ref pos, ts.Days, "d"); }); } /// <summary> Loading @@ -39,57 +51,88 @@ public static class SimpleTimeSpanExpress /// <returns></returns> public static TimeSpan ToTimeSpan(string str) { var timespan = TimeSpan.Zero; timespan = timespan.Add(TimeSpan.FromDays(Parse(str, "d"))); timespan = timespan.Add(TimeSpan.FromHours(Parse(str, "h"))); timespan = timespan.Add(TimeSpan.FromMinutes(Parse(str, "m"))); timespan = timespan.Add(TimeSpan.FromSeconds(Parse(str, "s"))); timespan = timespan.Add(TimeSpan.FromMilliseconds(Parse(str, "ms"))); timespan = timespan.Add(TimeSpan.FromMicroseconds(Parse(str, "us"))); var days = 0; var hours = 0; var minutes = 0; var seconds = 0; var milliseconds = 0; var microseconds = 0; return timespan; } var i = 0; var len = str.Length; private static void Append(int value, string unit, StringBuilder sb) while (i < len) { sb.Append($"{value}{unit}"); } public static int Parse(string s, string unit) { var sliced = s.Split(unit); if (str[i] == '-') throw new InvalidOperationException("值不能为负数。"); var str = Near(sliced[0]); if (!char.IsAsciiDigit(str[i])) throw new InvalidOperationException($"'{str[i]}' 不是有效的字符。"); if (int.TryParse(str, out var value)) var value = 0L; var numberStart = i; do { return value < 0 ? throw new InvalidOperationException("值不能为负数。") : value; } value = value * 10 + (str[i] - '0'); if (value > int.MaxValue) throw new InvalidOperationException( $"'{str.Substring(numberStart, i - numberStart + 1)}' 不是一个有效的32位整数。"); i++; } while (i < len && char.IsAsciiDigit(str[i])); throw new InvalidOperationException($"'{sliced[0]}' 不是一个有效的32位整数。"); } var unitStart = i; while (i < len && !char.IsAsciiDigit(str[i]) && str[i] != '-') i++; private static string Near(string s) { var arr = new char[s.Length]; var count = 0; var unitLen = i - unitStart; for (var i = s.Length - 1; i >= 0; i--) switch (unitLen) { if (char.IsAsciiDigit(s[i])) case 1: switch (str[unitStart]) { arr[i] = s[i]; count++; case 'd': days = (int)value; break; case 'h': hours = (int)value; break; case 'm': minutes = (int)value; break; case 's': seconds = (int)value; break; default: throw new InvalidOperationException($"'{str[unitStart]}' 不是有效的单位。"); } break; case 2: if (str[unitStart] == 'm' && str[unitStart + 1] == 's') milliseconds = (int)value; else if (str[unitStart] == 'u' && str[unitStart + 1] == 's') microseconds = (int)value; else throw new InvalidOperationException($"'{str.Substring(unitStart, 2)}' 不是有效的单位。"); break; default: throw new InvalidOperationException($"'{str.Substring(unitStart, unitLen)}' 不是有效的单位。"); } } if (count == 0) throw new InvalidOperationException("只包含非数字字符串。"); return new TimeSpan(days, hours, minutes, seconds, milliseconds, microseconds); } private static void AppendFromEnd(Span<char> span, ref int pos, int value, string unit) { for (var j = unit.Length - 1; j >= 0; j--) span[--pos] = unit[j]; var negative = value < 0; var v = negative ? -(long)value : value; do { span[--pos] = (char)('0' + v % 10); v /= 10; } while (v != 0); return new string(arr, arr.Length - count, count); if (negative) span[--pos] = '-'; } private static int GetStringLengthFast(int value) Loading Loading
src/VideoSlice.Cli/SimpleTimeSpanExpress.cs +100 −57 Original line number Diff line number Diff line using System.Text; using System; namespace VideoSlice.Cli; Loading @@ -11,25 +11,37 @@ public static class SimpleTimeSpanExpress /// <returns>时间表达式</returns> public static string ToString(TimeSpan timeSpan) { var days = timeSpan.Days; var hours = timeSpan.Hours; var minutes = timeSpan.Minutes; var seconds = timeSpan.Seconds; var milliseconds = timeSpan.Milliseconds; var microseconds = timeSpan.Microseconds; var len = GetStringLengthFast(timeSpan.Days) + 1 + GetStringLengthFast(timeSpan.Hours) + 1 + GetStringLengthFast(timeSpan.Minutes) + 1 + GetStringLengthFast(timeSpan.Seconds) + 1 + GetStringLengthFast(timeSpan.Milliseconds) + 2 + GetStringLengthFast(timeSpan.Microseconds) + 2 + 4; var sb = new StringBuilder(len); Append(timeSpan.Days, "d", sb); Append(timeSpan.Hours, "h", sb); Append(timeSpan.Minutes, "m", sb); Append(timeSpan.Seconds, "s", sb); Append(timeSpan.Milliseconds, "ms", sb); Append(timeSpan.Microseconds, "us", sb); return sb.ToString(); GetStringLengthFast(days) + 1 + GetStringLengthFast(hours) + 1 + GetStringLengthFast(minutes) + 1 + GetStringLengthFast(seconds) + 1; if (milliseconds != 0) len += GetStringLengthFast(milliseconds) + 2; if (microseconds != 0) len += GetStringLengthFast(microseconds) + 2; return string.Create(len, timeSpan, static (span, ts) => { var pos = span.Length; if (ts.Microseconds != 0) AppendFromEnd(span, ref pos, ts.Microseconds, "us"); if (ts.Milliseconds != 0) AppendFromEnd(span, ref pos, ts.Milliseconds, "ms"); AppendFromEnd(span, ref pos, ts.Seconds, "s"); AppendFromEnd(span, ref pos, ts.Minutes, "m"); AppendFromEnd(span, ref pos, ts.Hours, "h"); AppendFromEnd(span, ref pos, ts.Days, "d"); }); } /// <summary> Loading @@ -39,57 +51,88 @@ public static class SimpleTimeSpanExpress /// <returns></returns> public static TimeSpan ToTimeSpan(string str) { var timespan = TimeSpan.Zero; timespan = timespan.Add(TimeSpan.FromDays(Parse(str, "d"))); timespan = timespan.Add(TimeSpan.FromHours(Parse(str, "h"))); timespan = timespan.Add(TimeSpan.FromMinutes(Parse(str, "m"))); timespan = timespan.Add(TimeSpan.FromSeconds(Parse(str, "s"))); timespan = timespan.Add(TimeSpan.FromMilliseconds(Parse(str, "ms"))); timespan = timespan.Add(TimeSpan.FromMicroseconds(Parse(str, "us"))); var days = 0; var hours = 0; var minutes = 0; var seconds = 0; var milliseconds = 0; var microseconds = 0; return timespan; } var i = 0; var len = str.Length; private static void Append(int value, string unit, StringBuilder sb) while (i < len) { sb.Append($"{value}{unit}"); } public static int Parse(string s, string unit) { var sliced = s.Split(unit); if (str[i] == '-') throw new InvalidOperationException("值不能为负数。"); var str = Near(sliced[0]); if (!char.IsAsciiDigit(str[i])) throw new InvalidOperationException($"'{str[i]}' 不是有效的字符。"); if (int.TryParse(str, out var value)) var value = 0L; var numberStart = i; do { return value < 0 ? throw new InvalidOperationException("值不能为负数。") : value; } value = value * 10 + (str[i] - '0'); if (value > int.MaxValue) throw new InvalidOperationException( $"'{str.Substring(numberStart, i - numberStart + 1)}' 不是一个有效的32位整数。"); i++; } while (i < len && char.IsAsciiDigit(str[i])); throw new InvalidOperationException($"'{sliced[0]}' 不是一个有效的32位整数。"); } var unitStart = i; while (i < len && !char.IsAsciiDigit(str[i]) && str[i] != '-') i++; private static string Near(string s) { var arr = new char[s.Length]; var count = 0; var unitLen = i - unitStart; for (var i = s.Length - 1; i >= 0; i--) switch (unitLen) { if (char.IsAsciiDigit(s[i])) case 1: switch (str[unitStart]) { arr[i] = s[i]; count++; case 'd': days = (int)value; break; case 'h': hours = (int)value; break; case 'm': minutes = (int)value; break; case 's': seconds = (int)value; break; default: throw new InvalidOperationException($"'{str[unitStart]}' 不是有效的单位。"); } break; case 2: if (str[unitStart] == 'm' && str[unitStart + 1] == 's') milliseconds = (int)value; else if (str[unitStart] == 'u' && str[unitStart + 1] == 's') microseconds = (int)value; else throw new InvalidOperationException($"'{str.Substring(unitStart, 2)}' 不是有效的单位。"); break; default: throw new InvalidOperationException($"'{str.Substring(unitStart, unitLen)}' 不是有效的单位。"); } } if (count == 0) throw new InvalidOperationException("只包含非数字字符串。"); return new TimeSpan(days, hours, minutes, seconds, milliseconds, microseconds); } private static void AppendFromEnd(Span<char> span, ref int pos, int value, string unit) { for (var j = unit.Length - 1; j >= 0; j--) span[--pos] = unit[j]; var negative = value < 0; var v = negative ? -(long)value : value; do { span[--pos] = (char)('0' + v % 10); v /= 10; } while (v != 0); return new string(arr, arr.Length - count, count); if (negative) span[--pos] = '-'; } private static int GetStringLengthFast(int value) Loading