Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }