diff options
Diffstat (limited to 'src/mscorlib/src/System/Globalization/TimeSpanFormat.cs')
-rw-r--r-- | src/mscorlib/src/System/Globalization/TimeSpanFormat.cs | 246 |
1 files changed, 151 insertions, 95 deletions
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs b/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs index e5e615f1b3..ca053eded3 100644 --- a/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs +++ b/src/mscorlib/src/System/Globalization/TimeSpanFormat.cs @@ -3,44 +3,51 @@ // See the LICENSE file in the project root for more information. // -namespace System.Globalization { - using System.Text; - using System; - using System.Diagnostics; - using System.Diagnostics.Contracts; - using System.Globalization; - internal static class TimeSpanFormat { - - private static String IntToString(int n, int digits) { +using System.Text; +using System; +using System.Diagnostics; +using System.Diagnostics.Contracts; +using System.Globalization; + +namespace System.Globalization +{ + internal static class TimeSpanFormat + { + private static String IntToString(int n, int digits) + { return ParseNumbers.IntToString(n, 10, digits, '0', 0); } - internal static readonly FormatLiterals PositiveInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(false /*isNegative*/); - internal static readonly FormatLiterals NegativeInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(true /*isNegative*/); + internal static readonly FormatLiterals PositiveInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(false /*isNegative*/); + internal static readonly FormatLiterals NegativeInvariantFormatLiterals = TimeSpanFormat.FormatLiterals.InitInvariant(true /*isNegative*/); - internal enum Pattern { - None = 0, + internal enum Pattern + { + None = 0, Minimum = 1, - Full = 2, - } + Full = 2, + } // // Format // // Actions: Main method called from TimeSpan.ToString // - internal static String Format(TimeSpan value, String format, IFormatProvider formatProvider) { + internal static String Format(TimeSpan value, String format, IFormatProvider formatProvider) + { if (format == null || format.Length == 0) format = "c"; // standard formats - if (format.Length == 1) { + if (format.Length == 1) + { char f = format[0]; if (f == 'c' || f == 't' || f == 'T') return FormatStandard(value, true, format, Pattern.Minimum); - if (f == 'g' || f == 'G') { + if (f == 'g' || f == 'G') + { Pattern pattern; DateTimeFormatInfo dtfi = DateTimeFormatInfo.GetInstance(formatProvider); @@ -52,10 +59,10 @@ namespace System.Globalization { pattern = Pattern.Minimum; else pattern = Pattern.Full; - + return FormatStandard(value, false, format, pattern); } - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); } return FormatCustomized(value, format, DateTimeFormatInfo.GetInstance(formatProvider)); @@ -66,32 +73,37 @@ namespace System.Globalization { // // Actions: Format the TimeSpan instance using the specified format. // - private static String FormatStandard(TimeSpan value, bool isInvariant, String format, Pattern pattern) { + private static String FormatStandard(TimeSpan value, bool isInvariant, String format, Pattern pattern) + { StringBuilder sb = StringBuilderCache.Acquire(); int day = (int)(value._ticks / TimeSpan.TicksPerDay); long time = value._ticks % TimeSpan.TicksPerDay; - if (value._ticks < 0) { + 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 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) { + if (isInvariant) + { if (value._ticks < 0) literal = NegativeInvariantFormatLiterals; else literal = PositiveInvariantFormatLiterals; } - else { + else + { literal = new FormatLiterals(); literal.Init(format, pattern == Pattern.Full); } - if (fraction != 0) { // truncate the partial second to the specified length + if (fraction != 0) + { // truncate the partial second to the specified length fraction = (int)((long)fraction / (long)Math.Pow(10, DateTimeFormat.MaxSecondsFractionDigits - literal.ff)); } @@ -99,7 +111,8 @@ namespace System.Globalization { // Pattern.Minimum: [-][d.]hh:mm:ss[.fffffff] sb.Append(literal.Start); // [-] - if (pattern == Pattern.Full || day != 0) { // + if (pattern == Pattern.Full || day != 0) + { // sb.Append(day); // [dd] sb.Append(literal.DayHourSep); // [.] } // @@ -108,23 +121,29 @@ namespace System.Globalization { sb.Append(IntToString(minutes, literal.mm)); // mm sb.Append(literal.MinuteSecondSep); // : sb.Append(IntToString(seconds, literal.ss)); // ss - if (!isInvariant && pattern == Pattern.Minimum) { + if (!isInvariant && pattern == Pattern.Minimum) + { int effectiveDigits = literal.ff; - while (effectiveDigits > 0) { - if (fraction % 10 == 0) { + while (effectiveDigits > 0) + { + if (fraction % 10 == 0) + { fraction = fraction / 10; effectiveDigits--; } - else { + else + { break; } } - if (effectiveDigits > 0) { + 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) { + else if (pattern == Pattern.Full || fraction != 0) + { sb.Append(literal.SecondFractionSep); // [.] sb.Append(IntToString(fraction, literal.ff)); // [fffffff] } // @@ -141,47 +160,50 @@ namespace System.Globalization { // // Actions: Format the TimeSpan instance using the specified format. // - internal static String FormatCustomized(TimeSpan value, String format, DateTimeFormatInfo dtfi) { - + internal static String FormatCustomized(TimeSpan value, String format, DateTimeFormatInfo dtfi) + { Debug.Assert(dtfi != null, "dtfi == null"); int day = (int)(value._ticks / TimeSpan.TicksPerDay); long time = value._ticks % TimeSpan.TicksPerDay; - if (value._ticks < 0) { + 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 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(); - - while (i < format.Length) { + + while (i < format.Length) + { char ch = format[i]; int nextChar; - switch (ch) { + switch (ch) + { case 'h': tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 2) - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + 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(Environment.GetResourceString("Format_InvalidString")); + 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(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); DateTimeFormat.FormatDigits(result, seconds, tokenLen); break; case 'f': @@ -190,7 +212,7 @@ namespace System.Globalization { // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits) - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); tmp = (long)fraction; tmp /= (long)Math.Pow(10, DateTimeFormat.MaxSecondsFractionDigits - tokenLen); @@ -202,21 +224,25 @@ namespace System.Globalization { // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > DateTimeFormat.MaxSecondsFractionDigits) - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); tmp = (long)fraction; tmp /= (long)Math.Pow(10, DateTimeFormat.MaxSecondsFractionDigits - tokenLen); int effectiveDigits = tokenLen; - while (effectiveDigits > 0) { - if (tmp % 10 == 0) { + while (effectiveDigits > 0) + { + if (tmp % 10 == 0) + { tmp = tmp / 10; effectiveDigits--; } - else { + else + { break; } } - if (effectiveDigits > 0) { + if (effectiveDigits > 0) + { result.Append((tmp).ToString(DateTimeFormat.fixedNumberFormats[effectiveDigits - 1], CultureInfo.InvariantCulture)); } break; @@ -227,12 +253,12 @@ namespace System.Globalization { // tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 8) - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); DateTimeFormat.FormatDigits(result, day, tokenLen, true); break; case '\'': case '\"': - tokenLen = DateTimeFormat.ParseQuoteString(format, i, result); + tokenLen = DateTimeFormat.ParseQuoteString(format, i, result); break; case '%': // Optional format character. @@ -241,7 +267,8 @@ namespace System.Globalization { 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)'%') { + if (nextChar >= 0 && nextChar != (int)'%') + { result.Append(TimeSpanFormat.FormatCustomized(value, ((char)nextChar).ToString(), dtfi)); tokenLen = 2; } @@ -251,7 +278,7 @@ namespace System.Globalization { // This means that '%' is at the end of the format string or // "%%" appears in the format string. // - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); } break; case '\\': @@ -263,55 +290,67 @@ namespace System.Globalization { { result.Append(((char)nextChar)); tokenLen = 2; - } + } else { // // This means that '\' is at the end of the formatting string. // - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); } break; default: - throw new FormatException(Environment.GetResourceString("Format_InvalidString")); + throw new FormatException(SR.Format_InvalidString); } i += tokenLen; } return StringBuilderCache.GetStringAndRelease(result); - } - internal struct FormatLiterals { - internal String Start { - get { + internal struct FormatLiterals + { + internal String Start + { + get + { return literals[0]; } } - internal String DayHourSep { - get { + internal String DayHourSep + { + get + { return literals[1]; } } - internal String HourMinuteSep { - get { + internal String HourMinuteSep + { + get + { return literals[2]; } } - internal String MinuteSecondSep { - get { + internal String MinuteSecondSep + { + get + { return literals[3]; } } - internal String SecondFractionSep { - get { + internal String SecondFractionSep + { + get + { return literals[4]; } } - internal String End { - get { + internal String End + { + get + { return literals[5]; } } @@ -320,13 +359,14 @@ namespace System.Globalization { internal int hh; internal int mm; internal int ss; - internal int ff; + internal int ff; private String[] literals; /* factory method for static invariant FormatLiterals */ - internal static FormatLiterals InitInvariant(bool isNegative) { + internal static FormatLiterals InitInvariant(bool isNegative) + { FormatLiterals x = new FormatLiterals(); x.literals = new String[6]; x.literals[0] = isNegative ? "-" : String.Empty; @@ -334,7 +374,7 @@ namespace System.Globalization { x.literals[2] = ":"; x.literals[3] = ":"; x.literals[4] = "."; - x.literals[5] = String.Empty; + x.literals[5] = String.Empty; x.AppCompatLiteral = ":."; // MinuteSecondSep+SecondFractionSep; x.dd = 2; x.hh = 2; @@ -348,9 +388,10 @@ namespace System.Globalization { // the constants guaranteed to include DHMSF ordered greatest to least significant. // Once the data becomes more complex than this we will need to write a proper tokenizer for // parsing and formatting - internal void Init(String format, bool useInvariantFieldLengths) { + internal void Init(String format, bool useInvariantFieldLengths) + { literals = new String[6]; - for (int i = 0; i < literals.Length; i++) + for (int i = 0; i < literals.Length; i++) literals[i] = String.Empty; dd = 0; hh = 0; @@ -361,30 +402,37 @@ namespace System.Globalization { StringBuilder sb = StringBuilderCache.Acquire(); bool inQuote = false; char quote = '\''; - int field = 0; + int field = 0; - for (int i = 0; i < format.Length; i++) { - switch (format[i]) { + for (int i = 0; i < format.Length; i++) + { + switch (format[i]) + { case '\'': case '\"': - if (inQuote && (quote == format[i])) { + if (inQuote && (quote == format[i])) + { /* we were in a quote and found a matching exit quote, so we are outside a quote now */ Debug.Assert(field >= 0 && field <= 5, "field >= 0 && field <= 5"); - if (field >= 0 && field <= 5) { + if (field >= 0 && field <= 5) + { literals[field] = sb.ToString(); sb.Length = 0; inQuote = false; } - else { + else + { return; // how did we get here? } } - else if (!inQuote) { + else if (!inQuote) + { /* we are at the start of a new quote block */ quote = format[i]; inQuote = true; } - else { + else + { /* we were in a quote and saw the other type of quote character, so we are still in a quote */ } break; @@ -392,13 +440,15 @@ namespace System.Globalization { Debug.Assert(false, "Unexpected special token '%', Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); goto default; case '\\': - if (!inQuote) { + if (!inQuote) + { i++; /* skip next character that is escaped by this backslash or percent sign */ break; } goto default; case 'd': - if (!inQuote) { + if (!inQuote) + { Debug.Assert((field == 0 && sb.Length == 0) || field == 1, "field == 0 || field == 1, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 1; // DayHourSep @@ -406,7 +456,8 @@ namespace System.Globalization { } break; case 'h': - if (!inQuote) { + if (!inQuote) + { Debug.Assert((field == 1 && sb.Length == 0) || field == 2, "field == 1 || field == 2, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 2; // HourMinuteSep @@ -414,7 +465,8 @@ namespace System.Globalization { } break; case 'm': - if (!inQuote) { + if (!inQuote) + { Debug.Assert((field == 2 && sb.Length == 0) || field == 3, "field == 2 || field == 3, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 3; // MinuteSecondSep @@ -422,7 +474,8 @@ namespace System.Globalization { } break; case 's': - if (!inQuote) { + if (!inQuote) + { Debug.Assert((field == 3 && sb.Length == 0) || field == 4, "field == 3 || field == 4, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 4; // SecondFractionSep @@ -431,7 +484,8 @@ namespace System.Globalization { break; case 'f': case 'F': - if (!inQuote) { + if (!inQuote) + { Debug.Assert((field == 4 && sb.Length == 0) || field == 5, "field == 4 || field == 5, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 5; // End @@ -453,14 +507,16 @@ namespace System.Globalization { Debug.Assert(0 < ss && ss < 3, "0 < ss && ss < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); Debug.Assert(0 < ff && ff < 8, "0 < ff && ff < 8, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); - if (useInvariantFieldLengths) { + if (useInvariantFieldLengths) + { dd = 2; hh = 2; mm = 2; ss = 2; ff = DateTimeFormat.MaxSecondsFractionDigits; } - else { + else + { if (dd < 1 || dd > 2) dd = 2; // The DTFI property has a problem. let's try to make the best of the situation. if (hh < 1 || hh > 2) hh = 2; if (mm < 1 || mm > 2) mm = 2; |