/// <summary>Format the TimeSpan instance using the specified format.</summary> private static StringBuilder FormatCustomized(TimeSpan value, string format, DateTimeFormatInfo dtfi) { Debug.Assert(dtfi != null); int day = (int)(value.Ticks / TimeSpan.TicksPerDay); long time = value.Ticks % TimeSpan.TicksPerDay; if (value.Ticks < 0) { day = -day; time = -time; } int hours = (int)(time / TimeSpan.TicksPerHour % 24); int minutes = (int)(time / TimeSpan.TicksPerMinute % 60); int seconds = (int)(time / TimeSpan.TicksPerSecond % 60); int fraction = (int)(time % TimeSpan.TicksPerSecond); long tmp = 0; int i = 0; int tokenLen; StringBuilder result = StringBuilderCache.Acquire(InternalGlobalizationHelper.StringBuilderDefaultCapacity); while (i < format.Length) { char ch = format[i]; int nextChar; switch (ch) { case 'h': tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 2) { throw new FormatException(SR.Format_InvalidString); } DateTimeFormat.FormatDigits(result, hours, tokenLen); break; case 'm': tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 2) { throw new FormatException(SR.Format_InvalidString); } DateTimeFormat.FormatDigits(result, minutes, tokenLen); break; case 's': tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 2) { throw new FormatException(SR.Format_InvalidString); } DateTimeFormat.FormatDigits(result, seconds, tokenLen); break; case 'f': // // The fraction of a second in single-digit precision. The remaining digits are truncated. // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits) { throw new FormatException(SR.Format_InvalidString); } tmp = fraction; tmp /= TimeSpanParse.Pow10(DateTimeFormat.MaxSecondsFractionDigits - tokenLen); result.Append((tmp).ToString(DateTimeFormat.fixedNumberFormats[tokenLen - 1], CultureInfo.InvariantCulture)); break; case 'F': // // Displays the most significant digit of the seconds fraction. Nothing is displayed if the digit is zero. // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits) { throw new FormatException(SR.Format_InvalidString); } tmp = fraction; tmp /= TimeSpanParse.Pow10(DateTimeFormat.MaxSecondsFractionDigits - tokenLen); int effectiveDigits = tokenLen; while (effectiveDigits > 0) { if (tmp % 10 == 0) { tmp = tmp / 10; effectiveDigits--; } else { break; } } if (effectiveDigits > 0) { result.Append((tmp).ToString(DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture)); } break; case 'd': // // tokenLen == 1 : Day as digits with no leading zero. // tokenLen == 2+: Day as digits with leading zero for single-digit days. // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 8) { throw new FormatException(SR.Format_InvalidString); } DateTimeFormat.FormatDigits(result, day, tokenLen, true); break; case '\'': case '\"': tokenLen = DateTimeFormat.ParseQuoteString(format, i, result); break; case '%': // Optional format character. // For example, format string "%d" will print day // Most of the cases, "%" can be ignored. nextChar = DateTimeFormat.ParseNextChar(format, i); // nextChar will be -1 if we already reach the end of the format string. // Besides, we will not allow "%%" appear in the pattern. if (nextChar >= 0 && nextChar != (int)'%') { result.Append(TimeSpanFormat.FormatCustomized(value, ((char)nextChar).ToString(), dtfi)); tokenLen = 2; } else { // // This means that '%' is at the end of the format string or // "%%" appears in the format string. // throw new FormatException(SR.Format_InvalidString); } break; case '\\': // Escaped character. Can be used to insert character into the format string. // For example, "\d" will insert the character 'd' into the string. // nextChar = DateTimeFormat.ParseNextChar(format, i); if (nextChar >= 0) { result.Append(((char)nextChar)); tokenLen = 2; } else { // // This means that '\' is at the end of the formatting string. // throw new FormatException(SR.Format_InvalidString); } break; default: throw new FormatException(SR.Format_InvalidString); } i += tokenLen; } return(result); }
internal bool TryParse(string input, ref TimeSpanParse.TimeSpanResult result) { long num; result.parsedTimeSpan._ticks = 0L; if (input == null) { result.SetFailure(TimeSpanParse.ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "input"); return false; } this.str = input; this.len = input.Length; this.pos = -1; this.NextChar(); this.SkipBlanks(); bool flag = false; if (this.ch == '-') { flag = true; this.NextChar(); } if (this.NextNonDigit() == ':') { if (!this.ParseTime(out num, ref result)) { return false; } } else { int num2; if (!this.ParseInt(0xa2e3ff, out num2, ref result)) { return false; } num = num2 * 0xc92a69c000L; if (this.ch == '.') { long num3; this.NextChar(); if (!this.ParseTime(out num3, ref result)) { return false; } num += num3; } } if (flag) { num = -num; if (num > 0L) { result.SetFailure(TimeSpanParse.ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge"); return false; } } else if (num < 0L) { result.SetFailure(TimeSpanParse.ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge"); return false; } this.SkipBlanks(); if (this.pos < this.len) { result.SetFailure(TimeSpanParse.ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } result.parsedTimeSpan._ticks = num; return true; }
/// <summary>Format the TimeSpan instance using the specified format.</summary> private static StringBuilder FormatStandard(TimeSpan value, bool isInvariant, string format, Pattern pattern) { StringBuilder sb = StringBuilderCache.Acquire(InternalGlobalizationHelper.StringBuilderDefaultCapacity); int day = (int)(value.Ticks / TimeSpan.TicksPerDay); long time = value.Ticks % TimeSpan.TicksPerDay; if (value.Ticks < 0) { day = -day; time = -time; } int hours = (int)(time / TimeSpan.TicksPerHour % 24); int minutes = (int)(time / TimeSpan.TicksPerMinute % 60); int seconds = (int)(time / TimeSpan.TicksPerSecond % 60); int fraction = (int)(time % TimeSpan.TicksPerSecond); FormatLiterals literal; if (isInvariant) { literal = value.Ticks < 0 ? NegativeInvariantFormatLiterals : PositiveInvariantFormatLiterals; } else { literal = new FormatLiterals(); literal.Init(format, pattern == Pattern.Full); } if (fraction != 0) { // truncate the partial second to the specified length fraction = (int)(fraction / TimeSpanParse.Pow10(DateTimeFormat.MaxSecondsFractionDigits - literal.ff)); } // Pattern.Full: [-]dd.hh:mm:ss.fffffff // Pattern.Minimum: [-][d.]hh:mm:ss[.fffffff] sb.Append(literal.Start); // [-] if (pattern == Pattern.Full || day != 0) { sb.Append(day); // [dd] sb.Append(literal.DayHourSep); // [.] } // AppendNonNegativeInt32(sb, hours, literal.hh); // hh sb.Append(literal.HourMinuteSep); // : AppendNonNegativeInt32(sb, minutes, literal.mm); // mm sb.Append(literal.MinuteSecondSep); // : AppendNonNegativeInt32(sb, seconds, literal.ss); // ss if (!isInvariant && pattern == Pattern.Minimum) { int effectiveDigits = literal.ff; while (effectiveDigits > 0) { if (fraction % 10 == 0) { fraction = fraction / 10; effectiveDigits--; } else { break; } } if (effectiveDigits > 0) { sb.Append(literal.SecondFractionSep); // [.FFFFFFF] sb.Append((fraction).ToString(DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture)); } } else if (pattern == Pattern.Full || fraction != 0) { sb.Append(literal.SecondFractionSep); // [.] AppendNonNegativeInt32(sb, fraction, literal.ff); // [fffffff] } sb.Append(literal.End); return(sb); }
internal void SetFailure(TimeSpanParse.ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument) { this.SetFailure(failure, failureMessageID, failureMessageFormatArgument, null); }
internal void SetFailure(TimeSpanParse.ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument, string failureArgumentName) { this.m_failure = failure; this.m_failureMessageID = failureMessageID; this.m_failureMessageFormatArgument = failureMessageFormatArgument; this.m_failureArgumentName = failureArgumentName; if (this.throwStyle != TimeSpanParse.TimeSpanThrowStyle.None) { throw this.GetTimeSpanParseException(); } }
internal void Init(TimeSpanParse.TimeSpanThrowStyle canThrow) { this.parsedTimeSpan = new TimeSpan(); this.throwStyle = canThrow; }
internal void SetFailure(TimeSpanParse.ParseFailureKind failure, string failureMessageID) { this.SetFailure(failure, failureMessageID, null, null); }
private bool AddNum(TimeSpanParse.TimeSpanToken num, ref TimeSpanParse.TimeSpanResult result) { if ((this.NumCount >= 5) || (this.tokenCount >= 11)) { result.SetFailure(TimeSpanParse.ParseFailureKind.Format, "Format_BadTimeSpan", null); return false; } this.numbers[this.NumCount++] = num; this.tokenCount++; return true; }
private bool AddSep(string sep, ref TimeSpanParse.TimeSpanResult result) { if ((this.SepCount >= 6) || (this.tokenCount >= 11)) { result.SetFailure(TimeSpanParse.ParseFailureKind.Format, "Format_BadTimeSpan", null); return false; } this.literals[this.SepCount++] = sep; this.tokenCount++; return true; }
internal bool ProcessToken(ref TimeSpanParse.TimeSpanToken tok, ref TimeSpanParse.TimeSpanResult result) { if (tok.ttt == TimeSpanParse.TTT.NumOverflow) { result.SetFailure(TimeSpanParse.ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge", null); return false; } if ((tok.ttt != TimeSpanParse.TTT.Sep) && (tok.ttt != TimeSpanParse.TTT.Num)) { result.SetFailure(TimeSpanParse.ParseFailureKind.Format, "Format_BadTimeSpan", null); return false; } switch (tok.ttt) { case TimeSpanParse.TTT.Num: if ((this.tokenCount != 0) || this.AddSep(string.Empty, ref result)) { if (!this.AddNum(tok, ref result)) { return false; } break; } return false; case TimeSpanParse.TTT.Sep: if (this.AddSep(tok.sep, ref result)) { break; } return false; } this.lastSeenTTT = tok.ttt; return true; }
internal bool ParseTime(out long time, ref TimeSpanParse.TimeSpanResult result) { int num; time = 0L; if (!this.ParseInt(0x17, out num, ref result)) { return false; } time = num * 0x861c46800L; if (this.ch != ':') { result.SetFailure(TimeSpanParse.ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } this.NextChar(); if (!this.ParseInt(0x3b, out num, ref result)) { return false; } time += num * 0x23c34600L; if (this.ch == ':') { this.NextChar(); if (this.ch != '.') { if (!this.ParseInt(0x3b, out num, ref result)) { return false; } time += num * 0x989680L; } if (this.ch == '.') { this.NextChar(); int num2 = 0x989680; while (((num2 > 1) && (this.ch >= '0')) && (this.ch <= '9')) { num2 /= 10; time += (this.ch - '0') * num2; this.NextChar(); } } } return true; }
internal bool ParseInt(int max, out int i, ref TimeSpanParse.TimeSpanResult result) { i = 0; int pos = this.pos; while ((this.ch >= '0') && (this.ch <= '9')) { if ((((long) i) & 0xf0000000L) != 0L) { result.SetFailure(TimeSpanParse.ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge"); return false; } i = ((i * 10) + this.ch) - 0x30; if (i < 0) { result.SetFailure(TimeSpanParse.ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge"); return false; } this.NextChar(); } if (pos == this.pos) { result.SetFailure(TimeSpanParse.ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } if (i > max) { result.SetFailure(TimeSpanParse.ParseFailureKind.Overflow, "Overflow_TimeSpanElementTooLarge"); return false; } return true; }