コード例 #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
 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;
 }
コード例 #3
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);
        }
コード例 #4
0
 internal void SetFailure(TimeSpanParse.ParseFailureKind failure, string failureMessageID, object failureMessageFormatArgument)
 {
     this.SetFailure(failure, failureMessageID, failureMessageFormatArgument, null);
 }
コード例 #5
0
 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();
     }
 }
コード例 #6
0
 internal void Init(TimeSpanParse.TimeSpanThrowStyle canThrow)
 {
     this.parsedTimeSpan = new TimeSpan();
     this.throwStyle = canThrow;
 }
コード例 #7
0
 internal void SetFailure(TimeSpanParse.ParseFailureKind failure, string failureMessageID)
 {
     this.SetFailure(failure, failureMessageID, null, null);
 }
コード例 #8
0
 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;
 }
コード例 #9
0
 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;
 }
コード例 #10
0
            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;
            }
コード例 #11
0
 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;
 }
コード例 #12
0
 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;
 }