/// <summary> /// Token_Date follows the same rules for its parameters as Token_Int. It /// expects day to precede months, and months to precede years, but it can /// cope with D-M-Y and D-M-0 kinds of date. Token_Date is implemented as a /// state-based parser: /// /// State Next token Token means Go to state /// ----- ---------- ----------- ----------- /// -1 Error /// 0 Start of parsing Number Day of month 1 /// else -1 /// 1 Past day '/' or '-' Delimiter 2 /// JAN-DEC Month 3 /// else 2 /// 2 Numeric month 1-12 Month 3 /// else -1 /// 3 Past month '/' or '-' Delimiter 3 /// Number Year 4 /// else Year=0 4 /// </summary> /// <param name="InSt"></param> /// <param name="D"></param> /// <returns></returns> public static bool TokenDate(ref string InSt, ref int D) { bool result; // We need to have these in upper case as that is how TextToken returns them string[] MonthTexts = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; int State = 0; int Day = 0; int Mn = 0; int Yr = 0; while ((State != -1) && (State != 4)) { switch (State) { case 0: if (TokenInt(ref InSt, ref Day) && (Day >= 1) && (Day <= 31)) // State 0: we expect a number for the day { State = 1; } else { State = -1; } break; case 1: if ((MatchToken(ref InSt, "/") || MatchToken(ref InSt, "-"))) // State 1: Day found, looking for a { State = 2; // delimiter or a month text } else { Mn = 1; while ((Mn <= 12) && (!MatchToken(ref InSt, MonthTexts[Mn]))) { Mn++; } if (Mn <= 12) { State = 3; } else { State = 2; } } break; case 2: if (TokenInt(ref InSt, ref Mn) && (Mn >= 1) && (Mn <= 12)) // State 2: Day/month delimiter found, so { State = 3; // looking for a numeric month } else { State = -1; } break; case 3: if ((MatchToken(ref InSt, "/") || MatchToken(ref InSt, "-"))) // State 3: month has been found. Clear { State = 3; // away any delimiter and then look for a } else if (TokenInt(ref InSt, ref Yr) && (Yr >= 1)) // year { if (Yr < 100) { Yr = 1900 + Yr; } State = 4; // State=4 is the exit point } else { Yr = 0; State = 4; } break; } } if ((State != -1) && StdDate.DateValid(StdDate.DateVal(Day, Mn, Yr))) { result = true; D = StdDate.DateVal(Day, Mn, Yr); } else { result = false; } return(result); }
/// <summary> /// Token_Date follows the same rules for its parameters as Token_Int. It /// expects day to precede months, and months to precede years, but it can /// cope with D-M-Y and D-M-0 kinds of date. Token_Date is implemented as a /// state-based parser: /// ----- /// State Next token Token means Go to state /// ----- ---------- ----------- ----------- /// -1 Error /// 0 Start of parsing Number Day of month 1 /// else -1 /// 1 Past day '/' or '-' Delimiter 2 /// JAN-DEC Month 3 /// else 2 /// 2 Numeric month 1-12 Month 3 /// else -1 /// 3 Past month '/' or '-' Delimiter 3 /// Number Year 4 /// else Year=0 4 /// </summary> /// <param name="inputStr">Input date string</param> /// <param name="dateValue">Returned date</param> /// <returns>True is parsed ok</returns> public static bool TokenDate(ref string inputStr, ref int dateValue) { bool result; // We need to have these in upper case as that is how TextToken returns them string[] monthTexts = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" }; int state = 0; int day = 0; int mn = 0; int yr = 0; while ((state != -1) && (state != 4)) { switch (state) { case 0: if (TokenInt(ref inputStr, ref day) && (day >= 1) && (day <= 31)) // state 0: we expect a number for the day { state = 1; } else { state = -1; } break; case 1: if (MatchToken(ref inputStr, "/") || MatchToken(ref inputStr, "-")) // State 1: Day found, looking for a { state = 2; // delimiter or a month text } else { mn = 1; while ((mn <= 12) && (!MatchToken(ref inputStr, monthTexts[mn]))) { mn++; } if (mn <= 12) { state = 3; } else { state = 2; } } break; case 2: if (TokenInt(ref inputStr, ref mn) && (mn >= 1) && (mn <= 12)) // State 2: Day/month delimiter found, so { state = 3; // looking for a numeric month } else { state = -1; } break; case 3: if (MatchToken(ref inputStr, "/") || MatchToken(ref inputStr, "-")) // State 3: month has been found. Clear { state = 3; // away any delimiter and then look for a } else if (TokenInt(ref inputStr, ref yr) && (yr >= 1)) // year { if (yr < 100) { yr = 1900 + yr; } state = 4; // state=4 is the exit point } else { yr = 0; state = 4; } break; } } if ((state != -1) && StdDate.DateValid(StdDate.DateVal(day, mn, yr))) { result = true; dateValue = StdDate.DateVal(day, mn, yr); } else { result = false; } return(result); }