Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Globalization / TimeSpanFormat.cs / 1305376 / TimeSpanFormat.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //[....] // namespace System.Globalization { using System.Text; using System; using System.Diagnostics.Contracts; using System.Globalization; internal static class TimeSpanFormat { [System.Security.SecuritySafeCritical] // auto-generated 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 enum Pattern { None = 0, Minimum = 1, Full = 2, } // // Format // // Actions: Main method called from TimeSpan.ToString // internal static String Format(TimeSpan value, String format, IFormatProvider formatProvider) { if (format == null || format.Length == 0) format = "c"; // standard formats 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') { Pattern pattern; DateTimeFormatInfo dtfi = DateTimeFormatInfo.GetInstance(formatProvider); if (value._ticks < 0) format = dtfi.FullTimeSpanNegativePattern; else format = dtfi.FullTimeSpanPositivePattern; if (f == 'g') pattern = Pattern.Minimum; else pattern = Pattern.Full; return FormatStandard(value, false, format, pattern); } throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } return FormatCustomized(value, format, DateTimeFormatInfo.GetInstance(formatProvider)); } // // FormatStandard // // Actions: Format the TimeSpan instance using the specified format. // private static String FormatStandard(TimeSpan value, bool isInvariant, String format, Pattern pattern) { StringBuilder sb = new StringBuilder(); 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) { if (value._ticks < 0) literal = NegativeInvariantFormatLiterals; else literal = PositiveInvariantFormatLiterals; } else { literal = new FormatLiterals(); literal.Init(format, pattern == Pattern.Full); } if (fraction != 0) { // truncate the partial second to the specified length fraction = (int)((long)fraction / (long)Math.Pow(10, 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); // [.] } // sb.Append(IntToString(hours, literal.hh)); // hh sb.Append(literal.HourMinuteSep); // : sb.Append(IntToString(minutes, literal.mm)); // mm sb.Append(literal.MinuteSecondSep); // : sb.Append(IntToString(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); // [.] sb.Append(IntToString(fraction, literal.ff)); // [fffffff] } // sb.Append(literal.End); // return sb.ToString(); } // // FormatCustomized // // Actions: Format the TimeSpan instance using the specified format. // internal static String FormatCustomized(TimeSpan value, String format, DateTimeFormatInfo dtfi) { Contract.Assert(dtfi != null, "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 = new StringBuilder(); 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(Environment.GetResourceString("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")); DateTimeFormat.FormatDigits(result, minutes, tokenLen); break; case 's': tokenLen = DateTimeFormat.ParseRepeatPattern(format, i, ch); if (tokenLen > 2) throw new FormatException(Environment.GetResourceString("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(Environment.GetResourceString("Format_InvalidString")); tmp = (long)fraction; tmp /= (long)Math.Pow(10, 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(Environment.GetResourceString("Format_InvalidString")); tmp = (long)fraction; tmp /= (long)Math.Pow(10, 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(Environment.GetResourceString("Format_InvalidString")); DateTimeFormat.FormatDigits(result, day, tokenLen, true); break; case '\'': case '\"': StringBuilder enquotedString = new StringBuilder(); tokenLen = DateTimeFormat.ParseQuoteString(format, i, enquotedString); result.Append(enquotedString); 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(Environment.GetResourceString("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(Environment.GetResourceString("Format_InvalidString")); } break; default: throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } i += tokenLen; } return (result.ToString()); } internal struct FormatLiterals { internal String Start { get { return literals[0]; } } internal String DayHourSep { get { return literals[1]; } } internal String HourMinuteSep { get { return literals[2]; } } internal String MinuteSecondSep { get { return literals[3]; } } internal String SecondFractionSep { get { return literals[4]; } } internal String End { get { return literals[5]; } } internal String AppCompatLiteral; internal int dd; internal int hh; internal int mm; internal int ss; internal int ff; private String[] literals; /* factory method for static invariant FormatLiterals */ internal static FormatLiterals InitInvariant(bool isNegative) { FormatLiterals x = new FormatLiterals(); x.literals = new String[6]; x.literals[0] = isNegative ? "-" : String.Empty; x.literals[1] = "."; x.literals[2] = ":"; x.literals[3] = ":"; x.literals[4] = "."; x.literals[5] = String.Empty; x.AppCompatLiteral = ":."; // MinuteSecondSep+SecondFractionSep; x.dd = 2; x.hh = 2; x.mm = 2; x.ss = 2; x.ff = DateTimeFormat.MaxSecondsFractionDigits; return x; } // For the "v1" TimeSpan localized patterns, the data is simply literal field separators with // 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) { literals = new String[6]; for (int i = 0; i < literals.Length; i++) literals[i] = String.Empty; dd = 0; hh = 0; mm = 0; ss = 0; ff = 0; StringBuilder sb = new StringBuilder(); bool inQuote = false; char quote = '\''; int field = 0; for (int i = 0; i < format.Length; i++) { switch (format[i]) { case '\'': case '\"': if (inQuote && (quote == format[i])) { /* we were in a quote and found a matching exit quote, so we are outside a quote now */ Contract.Assert(field >= 0 && field <= 5, "field >= 0 && field <= 5"); if (field >= 0 && field <= 5) { literals[field] = sb.ToString(); sb.Length = 0; inQuote = false; } else { return; // how did we get here? } } else if (!inQuote) { /* we are at the start of a new quote block */ quote = format[i]; inQuote = true; } else { /* we were in a quote and saw the other type of quote character, so we are still in a quote */ } break; case '%': Contract.Assert(false, "Unexpected special token '%', Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); goto default; case '\\': if (!inQuote) { i++; /* skip next character that is escaped by this backslash or percent sign */ break; } goto default; case 'd': if (!inQuote) { Contract.Assert((field == 0 && sb.Length == 0) || field == 1, "field == 0 || field == 1, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 1; // DayHourSep dd++; } break; case 'h': if (!inQuote) { Contract.Assert((field == 1 && sb.Length == 0) || field == 2, "field == 1 || field == 2, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 2; // HourMinuteSep hh++; } break; case 'm': if (!inQuote) { Contract.Assert((field == 2 && sb.Length == 0) || field == 3, "field == 2 || field == 3, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 3; // MinuteSecondSep mm++; } break; case 's': if (!inQuote) { Contract.Assert((field == 3 && sb.Length == 0) || field == 4, "field == 3 || field == 4, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 4; // SecondFractionSep ss++; } break; case 'f': case 'F': if (!inQuote) { Contract.Assert((field == 4 && sb.Length == 0) || field == 5, "field == 4 || field == 5, Bug in DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); field = 5; // End ff++; } break; default: sb.Append(format[i]); break; } } Contract.Assert(field == 5); AppCompatLiteral = MinuteSecondSep + SecondFractionSep; Contract.Assert(0 < dd && dd < 3, "0 < dd && dd < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); Contract.Assert(0 < hh && hh < 3, "0 < hh && hh < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); Contract.Assert(0 < mm && mm < 3, "0 < mm && mm < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); Contract.Assert(0 < ss && ss < 3, "0 < ss && ss < 3, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); Contract.Assert(0 < ff && ff < 8, "0 < ff && ff < 8, Bug in System.Globalization.DateTimeFormatInfo.FullTimeSpan[Positive|Negative]Pattern"); if (useInvariantFieldLengths) { dd = 2; hh = 2; mm = 2; ss = 2; ff = DateTimeFormat.MaxSecondsFractionDigits; } 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; if (ss < 1 || ss > 2) ss = 2; if (ff < 1 || ff > 7) ff = 7; } } } //end of struct FormatLiterals } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ping.cs
- BitmapEffectInput.cs
- Environment.cs
- DataServiceQueryException.cs
- ResourceReferenceKeyNotFoundException.cs
- GenericParameterDataContract.cs
- safelink.cs
- OLEDB_Enum.cs
- InternalTypeHelper.cs
- ZoneIdentityPermission.cs
- SessionSymmetricTransportSecurityProtocolFactory.cs
- ObjRef.cs
- WebPartPersonalization.cs
- DBSqlParserTable.cs
- GuidelineCollection.cs
- ListViewItemSelectionChangedEvent.cs
- followingquery.cs
- SchemaMapping.cs
- EnumCodeDomSerializer.cs
- OdbcException.cs
- DataGridViewHitTestInfo.cs
- Cursors.cs
- LicFileLicenseProvider.cs
- MDIClient.cs
- listitem.cs
- LassoHelper.cs
- FreezableOperations.cs
- UpdateExpressionVisitor.cs
- StoreItemCollection.Loader.cs
- ServiceDesigner.cs
- ConfigXmlText.cs
- MemberCollection.cs
- TeredoHelper.cs
- ToolboxBitmapAttribute.cs
- StateChangeEvent.cs
- HelpKeywordAttribute.cs
- PropertyToken.cs
- Error.cs
- EventLog.cs
- DoubleAnimationClockResource.cs
- ArgumentNullException.cs
- XmlDataSourceView.cs
- ClientSettingsSection.cs
- SizeAnimationBase.cs
- ControlTemplate.cs
- TemplatedMailWebEventProvider.cs
- CodeTypeMember.cs
- TreeViewImageIndexConverter.cs
- ViewStateModeByIdAttribute.cs
- DataKeyArray.cs
- QilFactory.cs
- SR.cs
- xml.cs
- PageContentCollection.cs
- DataKeyCollection.cs
- __FastResourceComparer.cs
- EntityDesignerDataSourceView.cs
- DecimalAverageAggregationOperator.cs
- ReliableSessionBindingElement.cs
- DataKeyCollection.cs
- TextParagraphCache.cs
- ToolStripArrowRenderEventArgs.cs
- PropertyDescriptor.cs
- SoapExtensionImporter.cs
- PointLight.cs
- BitArray.cs
- Vertex.cs
- ActivityLocationReferenceEnvironment.cs
- IgnoreFileBuildProvider.cs
- StringConcat.cs
- DataGridCellsPresenter.cs
- RemoteDebugger.cs
- StrokeCollectionDefaultValueFactory.cs
- DESCryptoServiceProvider.cs
- EntityClassGenerator.cs
- ExeConfigurationFileMap.cs
- WindowsSysHeader.cs
- AdvancedBindingEditor.cs
- DetailsViewPagerRow.cs
- cookie.cs
- SmiEventSink_DeferedProcessing.cs
- latinshape.cs
- UniqueIdentifierService.cs
- EntityDataSourceDesignerHelper.cs
- XmlWrappingWriter.cs
- TextTreeUndoUnit.cs
- DBNull.cs
- Screen.cs
- ObjectQueryState.cs
- TransactionProtocol.cs
- DataServiceQueryProvider.cs
- Block.cs
- UriTemplateEquivalenceComparer.cs
- SQLMoney.cs
- SoapSchemaImporter.cs
- SemanticTag.cs
- objectquery_tresulttype.cs
- DSASignatureFormatter.cs
- NotSupportedException.cs
- HttpCacheParams.cs