private static bool CheckForQuestionMarks(ref GenDateInfo gdi, ref string sDate) { if (sDate.StartsWith("?")) { while (sDate.StartsWith("?")) sDate = sDate.Substring(1); gdi.prec = GenDate.PrecisionType.Approximate; if (sDate.Length == 0) gdi.error = gdi.year == 0; // ok if we already have a year. return true; } else { return false; } }
string ParseFormattedDate(string sDateString, string sFmt, out GenDateInfo gdi) { gdi = new GenDateInfo(); gdi.error = true; // just in case... gdi.prec = GenDate.PrecisionType.Exact; char ch; int i; int cch; bool fError; bool fDayPresent = false; bool fMonthPresent = false; bool fYearPresent = false; string sDate = sDateString.Trim(); for (; sFmt.Length > 0; sFmt = sFmt.Substring(cch)) { ch = sFmt[0]; for (i = 1; i < sFmt.Length; ++i) { if (sFmt[i] != ch) break; } cch = i; switch (ch) { case 'd': if (CheckForQuestionMarks(ref gdi, ref sDate)) { if (sDate.Length == 0) return String.Empty; else break; } switch (cch) { case 1: // d case 2: // dd fDayPresent = true; fError = !TryParseLeadingNumber(ref sDate, out gdi.mday); if (fError || gdi.mday > 31) return sDate; break; case 3: // ddd - Abbreviated day of week fError = !TryMatchAgainstNameList(ref sDate, m_rgsDayAbbr, out gdi.wday); if (fError) return sDate; break; case 4: // dddd - Unabbreviated day of the week fError = !TryMatchAgainstNameList(ref sDate, m_rgsDayName, out gdi.wday); if (fError) return sDate; break; default: return sDate; } break; case 'M': if (CheckForQuestionMarks(ref gdi, ref sDate)) { if (sDate.Length == 0) return String.Empty; else break; } fMonthPresent = true; switch (cch) { case 1: // M case 2: // MM fError = !TryParseLeadingNumber(ref sDate, out gdi.ymon); if (fError || gdi.ymon > 12) return sDate; break; case 3: // MMM - Abbreviated month name fError = !TryMatchAgainstNameList(ref sDate, m_rgsMonthAbbr, out gdi.ymon); if (fError) return sDate; break; case 4: // MMMM - Unabbreviated month name fError = !TryMatchAgainstNameList(ref sDate, m_rgsMonthName, out gdi.ymon); if (fError) return sDate; break; default: return sDate; } break; case 'y': if (sDate.StartsWith("?")) { gdi.error = true; return sDate; } fYearPresent = true; int year; int thisyear = DateTime.Now.Year; switch (cch) { case 1: fError = !TryParseLeadingNumber(ref sDate, out year); if (fError || year > 9) return sDate; gdi.year = 2000 + year; if (gdi.year > thisyear) gdi.year -= 100; break; case 2: fError = !TryParseLeadingNumber(ref sDate, out year); if (fError || year > 99) return sDate; gdi.year = 2000 + year; if (gdi.year > thisyear) gdi.year -= 100; break; case 4: fError = !TryParseLeadingNumber(ref sDate, out year); if (fError) return sDate; break; default: return sDate; } break; case 'g': // TODO SteveMc: IMPLEMENT ME! return sDate; case '\'': // quoted text //cch = ParseFmtQuotedText (sFmt, sDate); //if (cch < 0) // return 0; // text not found break; case ' ': sDate = sDate.Trim(); break; default: // Check for matching separators. sDate = sDate.Trim(); for (int j = 0; j < cch; ++j) { if (j >= sDate.Length || sDate[j] != ch) return sDate; } sDate = sDate.Substring(cch); sDate = sDate.Trim(); break; } } gdi.error = !ValidateDate(fYearPresent ? gdi.year : 2000, fMonthPresent ? gdi.ymon : 1, fDayPresent ? gdi.mday : 1); return sDate; }