/// <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); }
/// <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); }