// ---- SECTION: private static methods that do the actual work ---------* #region TryParseTimeSpan // // TryParseTimeSpan // // Actions: Common private Parse method called by both Parse and TryParse // private static Boolean TryParseTimeSpan(String input, TimeSpanStandardStyles style, IFormatProvider formatProvider, ref TimeSpanResult result) { if (input == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, nameof(input)); return false; } input = input.Trim(); if (input == String.Empty) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } TimeSpanTokenizer tokenizer = new TimeSpanTokenizer(); tokenizer.Init(input); TimeSpanRawInfo raw = new TimeSpanRawInfo(); raw.Init(DateTimeFormatInfo.GetInstance(formatProvider)); TimeSpanToken tok = tokenizer.GetNextToken(); /* The following loop will break out when we reach the end of the str or * when we can determine that the input is invalid. */ while (tok.ttt != TTT.End) { if (!raw.ProcessToken(ref tok, ref result)) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } tok = tokenizer.GetNextToken(); } if (!tokenizer.EOL) { // embedded nulls in the input string result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } if (!ProcessTerminalState(ref raw, style, ref result)) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } return true; }
// // ProcessTerminalState // // Actions: Validate the terminal state of a standard format parse. // Sets result.parsedTimeSpan on success. // // Calculates the resultant TimeSpan from the TimeSpanRawInfo // // try => +InvariantPattern, -InvariantPattern, +LocalizedPattern, -LocalizedPattern // 1) Verify Start matches // 2) Verify End matches // 3) 1 number => d // 2 numbers => h:m // 3 numbers => h:m:s | d.h:m | h:m:.f // 4 numbers => h:m:s.f | d.h:m:s | d.h:m:.f // 5 numbers => d.h:m:s.f private static Boolean ProcessTerminalState(ref TimeSpanRawInfo raw, TimeSpanStandardStyles style, ref TimeSpanResult result) { if (raw.lastSeenTTT == TTT.Num) { TimeSpanToken tok = new TimeSpanToken(); tok.ttt = TTT.Sep; tok.sep = String.Empty; if (!raw.ProcessToken(ref tok, ref result)) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } } switch (raw.NumCount) { case 1: return ProcessTerminal_D(ref raw, style, ref result); case 2: return ProcessTerminal_HM(ref raw, style, ref result); case 3: return ProcessTerminal_HM_S_D(ref raw, style, ref result); case 4: return ProcessTerminal_HMS_F_D(ref raw, style, ref result); case 5: return ProcessTerminal_DHMSF(ref raw, style, ref result); default: result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } }
private static bool TryParseTimeSpan(string input, TimeSpanStandardStyles style, IFormatProvider formatProvider, ref TimeSpanResult result) { if (input == null) { result.SetFailure(ParseFailureKind.ArgumentNull, "ArgumentNull_String", null, "input"); return false; } input = input.Trim(); if (input == string.Empty) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } TimeSpanTokenizer tokenizer = new TimeSpanTokenizer(); tokenizer.Init(input); TimeSpanRawInfo raw = new TimeSpanRawInfo(); raw.Init(DateTimeFormatInfo.GetInstance(formatProvider)); for (TimeSpanToken token = tokenizer.GetNextToken(); token.ttt != TTT.End; token = tokenizer.GetNextToken()) { if (!raw.ProcessToken(ref token, ref result)) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } } if (!tokenizer.EOL) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } if (!ProcessTerminalState(ref raw, style, ref result)) { result.SetFailure(ParseFailureKind.Format, "Format_BadTimeSpan"); return false; } return true; }