public override List <ParsedResult> Refine(string originalText, List <ParsedResult> results, Option opt) { if (results.Count < 2) { return(results); } var mergedResult = new List <ParsedResult>(); ParsedResult currResult = null; ParsedResult prevResult = null; for (var i = 1; i < results.Count; i++) { currResult = results[i]; prevResult = results[i - 1]; if (prevResult.End == null && currResult.End == null && IsAbleToMerge(originalText, prevResult, currResult)) { prevResult = this.MergeResult(originalText, prevResult, currResult); currResult = null; i += 1; } mergedResult.Add(prevResult); } if (currResult != null) { mergedResult.Add(currResult); } return(mergedResult); }
private void SetStartEndDates(ParsedResult result, DateTime date, DateTime reference) { ParsedComponents pivot = null; ParsedComponents node = null; result.End = result.End ?? result.Start.Clone() as ParsedComponents; if (Config.Direction == DateTimeDirection.Backward) { pivot = result.End; node = result.Start; } else { pivot = result.Start; node = result.End; } pivot.Imply("year", reference.Year); pivot.Imply("month", reference.Month); pivot.Imply("day", reference.Day); pivot.Imply("hour", reference.Hour); pivot.Imply("minute", reference.Minute); pivot.Imply("second", reference.Second); node.Imply("year", date.Year); node.Imply("month", date.Month); node.Imply("day", date.Day); node.Imply("hour", date.Hour); node.Imply("minute", date.Minute); node.Imply("second", date.Second); result.Tags[this.GetType().Name] = true; }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var text = match.Value.Trim(); if (String.IsNullOrWhiteSpace(text)) { return(null); } var result = new ParsedResult(new TemporalResult { Index = match.Index, Text = text, Reference = reference }); int year; if (int.TryParse(text, out year)) { result.Start.Assign("day", 1); result.Start.Assign("month", 1); result.Start.Assign("year", year); result.End = result.Start.Clone() as ParsedComponents; result.End.Assign("month", 12); result.Tags[this.GetType().Name] = true; } else { return(null); } return(result); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var text = match.Groups[0].Value.Substring(match.Groups[1].Length); var index = match.Index + match.Groups[1].Length; var result = new ParsedResult(new TemporalResult { Index = index, Text = text, Reference = reference }); var refMoment = GetMoment(reference); var startMoment = GetMoment(reference); var lowerText = text.ToLower(); if (String.Compare(lowerText, "tonight") == 0) { // Normally means this coming midnight result.Start.Imply("hour", 22); result.Start.Imply("meridiem", 1); } else if (new Regex("^tomorrow|^tmr").Match(lowerText).Success) { // Check not "Tomorrow" on late night if (refMoment.Hour > 1) { startMoment.Day += 1; } } else if (new Regex("^yesterday").Match(lowerText).Success) { startMoment.Day -= 1; } else if (new Regex(@"last\s*night").Match(lowerText).Success) { result.Start.Imply("hour", 0); if (refMoment.Hour > 6) { startMoment.Day -= 1;; } } else if (new Regex("now", RegexOptions.IgnoreCase).Match(lowerText).Success) { result.Start.Assign("hour", refMoment.Hour); result.Start.Assign("minute", refMoment.Minute); result.Start.Assign("second", refMoment.Second); result.Start.Assign("millisecond", refMoment.Millisecond); } result.Start.Assign("day", startMoment.Day); result.Start.Assign("month", startMoment.Month); result.Start.Assign("year", startMoment.Year); result.Tags["ENCasualDateParser"] = true; return(result); }
private bool IsAbleToMerge(string text, ParsedResult result1, ParsedResult result2) { var begin = result1.Index + result1.Text.Length; var end = result2.Index; string textBetween = String.Empty; if (end > begin) { textBetween = text.Substring(begin, (end - begin)); } else { textBetween = text.Substring(end, (begin - end)); //swap } return(Pattern.Match(textBetween).Success); }
protected void PredictAppropriateYear(DateTime?reference, int month, int day, ref ParsedResult result) { var refMoment = new DateTime(reference.Value.Year, month, day); var nextYear = new DateTime(refMoment.Year + 1, refMoment.Month, refMoment.Day); var lastYear = new DateTime(refMoment.Year - 1, refMoment.Month, refMoment.Day); var distanceToCurrentYearDate = (refMoment - reference.Value).TotalHours; var distanceToNextYearDate = (nextYear - reference.Value).TotalHours; var distanceToPreviousYearDate = (lastYear - reference.Value).TotalHours; if (Config.Direction == DateTimeDirection.Default) { //set the year based on nearest of the 3 dates from now //- the one in previous year //- the one in current year //- the one in next year if (Math.Abs(distanceToNextYearDate) < Math.Abs(distanceToCurrentYearDate)) { refMoment = nextYear; } else if (Math.Abs(distanceToPreviousYearDate) < Math.Abs(distanceToCurrentYearDate)) { refMoment = lastYear; } } //if distance to current year is positive with always-backward config, set to last year, else set to current year else if (Config.Direction == DateTimeDirection.Backward && distanceToCurrentYearDate > 0) { refMoment = lastYear; } //if distance to current year is negative with always-forward config, set to next year, else set to current year else if (Config.Direction == DateTimeDirection.Forward && distanceToCurrentYearDate < 0) { refMoment = nextYear; } result.Start.Assign("day", day); result.Start.Assign("month", month); result.Start.Imply("year", refMoment.Year); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var index = match.Index + match.Groups[1].Length; var text = match.Groups[0].Value.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length); var result = new ParsedResult(new TemporalResult { Text = text, Index = index, Reference = reference }); var numStr = match.Groups[3].Value.ToLower(); INTEGER_WORDS numEnum; int num = -1; if (Enum.TryParse(numStr, true, out numEnum) && Enum.IsDefined(typeof(INTEGER_WORDS), numEnum)) { num = (int)numEnum; } else if (String.Compare(numStr, "a", true) == 0 || String.Compare(numStr, "an", true) == 0) { num = 1; } else if (new Regex("few", RegexOptions.IgnoreCase).Match(numStr).Success) { num = 3; } else if (new Regex("half", RegexOptions.IgnoreCase).Match(numStr).Success) { //let's take care of half if the requirement comes! //num = 0.5; } else { int.TryParse(numStr, out num); //failed int.parse => num = 0 } DateTime date = new DateTime(reference.Value.Year, reference.Value.Month, reference.Value.Day); if (new Regex("day|week|month|year", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (new Regex("day", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddDays(-num); } else { date = date.AddDays(num); } } else if (new Regex("week", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddDays(-num * 7); } else { date = date.AddDays(num * 7); } } else if (new Regex("month", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddMonths(-num); } else { date = date.AddMonths(num); } } else if (new Regex("year", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddYears(-num); } else { date = date.AddYears(num); } } } else if (new Regex("hour", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddHours(-num); } else { date = date.AddHours(num); } } else if (new Regex("min", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddMinutes(-num); } else { date = date.AddMinutes(num); } } else if (new Regex("second", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success) { if (Config.Direction == DateTimeDirection.Backward) { date = date.AddSeconds(-num); } else { date = date.AddSeconds(num); } } SetStartEndDates(result, date, reference ?? DateTime.Now); return(result); }
private ParsedResult MergeResult(string text, ParsedResult fromResult, ParsedResult toResult) { if (!IsWeekdayResult(fromResult) && !IsWeekdayResult(toResult)) { foreach (var kvp in toResult.Start.knownValues) { if (!fromResult.Start.IsCertain(kvp.Key)) { fromResult.Start.Assign(kvp.Key, toResult.Start.GetValue(kvp.Key)); } } foreach (var kvp in fromResult.Start.knownValues) { if (!toResult.Start.IsCertain(kvp.Key)) { toResult.Start.Assign(kvp.Key, fromResult.Start.GetValue(kvp.Key)); } } } if (fromResult.Start.Date > toResult.Start.Date) { var fromMoment = fromResult.Start.Date; var toMoment = toResult.Start.Date; if (IsWeekdayResult(fromResult) && fromMoment.AddDays(-7) < toMoment) { fromMoment = fromMoment.AddDays(-7); fromResult.Start.Imply("day", fromMoment.Day); fromResult.Start.Imply("month", fromMoment.Month); fromResult.Start.Imply("year", fromMoment.Year); } else if (this.IsWeekdayResult(toResult) && toMoment.AddDays(7) > fromMoment) { toMoment = toMoment.AddDays(7); toResult.Start.Imply("day", toMoment.Day); toResult.Start.Imply("month", toMoment.Month); toResult.Start.Imply("year", toMoment.Year); } else { var tmp = toResult; toResult = fromResult; fromResult = tmp; } } fromResult.End = toResult.Start; foreach (var tag in toResult.Tags) { fromResult.Tags[tag.Key] = true; } var startIndex = Math.Min(fromResult.Index, toResult.Index); var endIndex = Math.Max( fromResult.Index + fromResult.Text.Length, toResult.Index + toResult.Text.Length); fromResult.Index = startIndex; fromResult.Text = text.Substring(startIndex, (endIndex - startIndex)); fromResult.Tags["ENMergeDateTimeRefiner"] = true; return(fromResult); }
private bool IsWeekdayResult(ParsedResult result) { return(result.Start.IsCertain("weekday") && !result.Start.IsCertain("day")); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { // This pattern can be overlaped Ex. [12] AM, 1[2] AM if (match.Index > 0 && new Regex(@"/\w/", RegexOptions.IgnoreCase).Match(originalText[match.Index - 1].ToString()).Success) { return(null); } int index = match.Index + match.Groups[1].Length; string text = match.Groups[0].Value.Substring(match.Groups[1].Length); var result = new ParsedResult(new TemporalResult { Text = text, Index = index, Reference = reference }); result.Tags["ENTimeExpressionParser"] = true; result.Start.Imply("day", reference.Value.Day); result.Start.Imply("month", reference.Value.Month); result.Start.Imply("year", reference.Value.Year); var hour = 0; var minute = 0; var meridiem = -1; // ----- Millisecond if (match.Groups[MILLI_SECOND_GROUP].Captures.Count != 0) { int millisecond = 0; int.TryParse(match.Groups[MILLI_SECOND_GROUP].Value.Substring(0, 3), out millisecond); if (millisecond >= 1000) { return(null); } result.Start.Assign("millisecond", millisecond); } // ----- Second if (match.Groups[SECOND_GROUP].Captures.Count != 0) { int second = 0; int.TryParse(match.Groups[SECOND_GROUP].Value, out second); if (second >= 60) { return(null); } result.Start.Assign("second", second); } // ----- Hours if (String.Compare(match.Groups[HOUR_GROUP].Value.ToLower(), "noon", true) == 0) { meridiem = 1; hour = 12; } else if (String.Compare(match.Groups[HOUR_GROUP].Value.ToLower(), "midnight", true) == 0) { meridiem = 0; hour = 0; } else { int.TryParse(match.Groups[HOUR_GROUP].Value, out hour); } // ----- Minutes if (match.Groups[MINUTE_GROUP].Captures.Count != 0) { int.TryParse(match.Groups[MINUTE_GROUP].Value, out minute); } else if (hour > 100) { minute = hour % 100; hour = (int)(hour / 100); } if (minute >= 60) { return(null); } if (hour > 24) { return(null); } if (hour >= 12) { meridiem = 1; } // ----- AM & PM if (match.Groups[AM_PM_HOUR_GROUP].Captures.Count != 0) { if (hour > 12) { return(null); } var ampm = match.Groups[AM_PM_HOUR_GROUP].Captures[0].Value.ToLower(); if (String.Compare(ampm, "a", true) == 0) { meridiem = 0; if (hour == 12) { hour = 0; } } if (String.Compare(ampm, "p", true) == 0) { meridiem = 1; if (hour != 12) { hour += 12; } } } result.Start.Assign("hour", hour); result.Start.Assign("minute", minute); if (meridiem >= 0) { result.Start.Assign("meridiem", meridiem); } else { if (hour < 12) { result.Start.Imply("meridiem", 0); } else { result.Start.Imply("meridiem", 1); } } // ============================================================== // Extracting the "to" chunk // ============================================================== match = SECOND_REG_PATTERN.Match(originalText.Substring(result.Index + result.Text.Length)); if (!match.Success) { // Not accept number only result if (new Regex(@"/^\d+$/", RegexOptions.IgnoreCase).Match(result.Text).Success) { return(null); } return(result); } // Pattern "YY.YY -XXXX" is more like timezone offset if (new Regex((@"/^\s*(\+|\-)\s*\d{3,4}$/"), RegexOptions.IgnoreCase).Match(match.Groups[0].Value).Success) { return(result); } if (result.End == null) { result.End = new ParsedComponents(null, result.Start.Date); } hour = 0; minute = 0; meridiem = -1; // ----- Millisecond if (match.Groups[MILLI_SECOND_GROUP].Captures.Count != 0) { int millisecond; int.TryParse(match.Groups[MILLI_SECOND_GROUP].Value.Substring(0, 3), out millisecond); if (millisecond >= 1000) { return(null); } result.End.Assign("millisecond", millisecond); } // ----- Second if (match.Groups[SECOND_GROUP].Captures.Count != 0) { int second; int.TryParse(match.Groups[SECOND_GROUP].Value, out second); if (second >= 60) { return(null); } result.End.Assign("second", second); } int.TryParse(match.Groups[2].Value, out hour); // ----- Minute if (match.Groups[MINUTE_GROUP].Captures.Count != 0) { int.TryParse(match.Groups[MINUTE_GROUP].Value, out minute); if (minute >= 60) { return(result); } } else if (hour > 100) { minute = hour % 100; hour = (int)(hour / 100); } if (minute >= 60) { return(null); } if (hour > 24) { return(null); } if (hour >= 12) { meridiem = 1; } // ----- AM & PM if (match.Groups[AM_PM_HOUR_GROUP].Captures.Count != 0) { if (hour > 12) { return(null); } var ampm = match.Groups[AM_PM_HOUR_GROUP].Captures[0].Value.ToLower(); if (String.Compare(ampm, "a", true) == 0) { meridiem = 0; if (hour == 12) { hour = 0; if (!result.End.IsCertain("day")) { result.End.Imply("day", result.End.GetValue("day") + 1); } } } if (ampm == "p") { meridiem = 1; if (hour != 12) { hour += 12; } } if (!result.Start.IsCertain("meridiem")) { if (meridiem == 0) { result.Start.Imply("meridiem", 0); if (result.Start.GetValue("hour") == 12) { result.Start.Assign("hour", 0); } } else { result.Start.Imply("meridiem", 1); if (result.Start.GetValue("hour") != 12) { result.Start.Assign("hour", result.Start.GetValue("hour") + 12); } } } } result.Text = result.Text + match.Groups[0].Value; result.End.Assign("hour", hour); result.End.Assign("minute", minute); if (meridiem >= 0) { result.End.Assign("meridiem", meridiem); } else { var startAtPM = result.Start.IsCertain("meridiem") && result.Start.GetValue("meridiem") == 1; if (startAtPM && result.Start.GetValue("hour") > hour) { // 10pm - 1 (am) result.End.Imply("meridiem", 0); } else if (hour > 12) { result.End.Imply("meridiem", 1); } } if (result.End.Date < result.Start.Date) { result.End.Imply("day", result.End.GetValue("day") + 1); } return(result); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var text = match.Groups[0].Value.Substring(match.Groups[1].Length); var index = match.Index + match.Groups[1].Length; var result = new ParsedResult(new TemporalResult { Index = index, Text = text, Reference = reference }); var refMoment = GetMoment(reference); var startMoment = GetMoment(reference); Moment endMoment = null; var lowerText = text.ToLower(); if (new Regex(@"(\W|^)(latest|recent)|((last|latest|recent|previous)?\s*months?)").Match(lowerText).Success) { startMoment.Month -= 1; if (startMoment.Month == 0) //move to last year { startMoment.Year -= 1; } } else if (new Regex(@"(\W|^)(latest|recent)|((last|latest|recent|previous)\s*quarters?)").Match(lowerText).Success) { SetDateRangeForQuarterOffset(-1, ref startMoment, ref endMoment); } else if (new Regex(@"(\W|^)(current|present)|((this|current|present)\s*quarters?)").Match(lowerText).Success) { SetDateRangeForQuarterOffset(-1, ref startMoment, ref endMoment); } else if (new Regex(@"(\W|^)((last|latest|recent|previous)\s*years?)").Match(lowerText).Success) { startMoment.Year -= 1; startMoment.Month = 1; endMoment = GetMoment(startMoment.DateTime()); endMoment.Month = 12; } else if (new Regex(@"(\W|^)((this|current|present)\s*years?)").Match(lowerText).Success) { startMoment.Month = 1; endMoment = GetMoment(startMoment.DateTime()); endMoment.Month = 12; } else if (new Regex(@"(\W|^)(annual|trends?|evolutions?|movements?|progressions?)").Match(lowerText).Success) { //last 12 months startMoment.Year -= 1; endMoment = GetMoment(startMoment.DateTime()); endMoment.Month += 11; if (endMoment.Month > 12) { //move to next year endMoment.Year += 1; endMoment.Month -= 12; } } else if (match.Groups[7].Captures.Count > 0) //things like 3rd,4th.. comes in 7th group { int qrtr; var qrtrStr = match.Groups[7].Value.Trim().Replace('_', ' ').ToLower(); if (int.TryParse(qrtrStr, out qrtr)) { SetDateRangeForQuarterIndex(qrtr, ref startMoment, ref endMoment); } } else if (match.Groups[6].Captures.Count > 0) //ordinal number comes in 6th group { var ordinalStr = match.Groups[6].Value.Trim().Replace('_', ' ').ToLower(); ORDINAL_WORDS ordinalEnum; if (Enum.TryParse(ordinalStr, true, out ordinalEnum) && Enum.IsDefined(typeof(ORDINAL_WORDS), ordinalEnum)) { SetDateRangeForQuarterIndex((int)ordinalEnum, ref startMoment, ref endMoment); } } result.Start.Assign("day", startMoment.Day); result.Start.Assign("month", startMoment.Month); result.Start.Assign("year", startMoment.Year); if (endMoment != null) { result.End = result.End ?? result.Start.Clone() as ParsedComponents; result.End.Assign("day", endMoment.Day); result.End.Assign("month", endMoment.Month); result.End.Assign("year", endMoment.Year); } result.Tags[this.GetType().Name] = true; return(result); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var text = match.Groups[0].Value.Substring(match.Groups[1].Length); var index = match.Index + match.Groups[1].Length; var result = new ParsedResult(new TemporalResult { Text = text, Index = index, Reference = reference }); result.Start.Assign("year", int.Parse(match.Groups[YEAR_NUMBER_GROUP].Value)); result.Start.Assign("month", int.Parse(match.Groups[MONTH_NUMBER_GROUP].Value)); result.Start.Assign("day", int.Parse(match.Groups[DATE_NUMBER_GROUP].Value)); //validation if (result.Start.GetValue("month") > 12 || result.Start.GetValue("month") < 1 || result.Start.GetValue("day") > 31 || result.Start.GetValue("day") < 1) { return(null); } if (!String.IsNullOrWhiteSpace(match.Groups[HOUR_NUMBER_GROUP].Value)) { result.Start.Assign("hour", int.Parse(match.Groups[HOUR_NUMBER_GROUP].Value)); result.Start.Assign("minute", int.Parse(match.Groups[MINUTE_NUMBER_GROUP].Value)); if (!String.IsNullOrWhiteSpace(match.Groups[SECOND_NUMBER_GROUP].Value)) { result.Start.Assign("second", int.Parse(match.Groups[SECOND_NUMBER_GROUP].Value)); } if (!String.IsNullOrWhiteSpace(match.Groups[MILLISECOND_NUMBER_GROUP].Value)) { result.Start.Assign("millisecond", int.Parse(match.Groups[MILLISECOND_NUMBER_GROUP].Value)); } if (!String.IsNullOrWhiteSpace(match.Groups[TZD_HOUR_OFFSET_GROUP].Value)) { result.Start.Assign("timezoneOffset", 0); } else { var minuteOffset = 0; var hourOffset = int.Parse(match.Groups[TZD_HOUR_OFFSET_GROUP].Value); if (!String.IsNullOrWhiteSpace(match.Groups[TZD_MINUTE_OFFSET_GROUP].Value)) { minuteOffset = int.Parse(match.Groups[TZD_MINUTE_OFFSET_GROUP].Value); } var offset = hourOffset * 60; if (offset < 0) { offset -= minuteOffset; } else { offset += minuteOffset; } result.Start.Assign("timezoneOffset", offset); } } result.Tags["ENISOFormatParser"] = true; return(result); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var text = match.Groups[0].Value.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length); var index = match.Index + match.Groups[1].Length; var result = new ParsedResult(new TemporalResult { Text = text, Index = index, Reference = reference }); var monthStr = match.Groups[MONTH_NAME_GROUP].Value.ToLower(); MONTH_OFFSET monthEnum; int month = -1; if (Enum.TryParse(monthStr, true, out monthEnum) && Enum.IsDefined(typeof(MONTH_OFFSET), monthEnum)) { month = (int)monthEnum; } else { int.TryParse(monthStr, out month); } string dayStr = null; ORDINAL_WORDS dayEnum; int day = -1; if (match.Groups[DATE_NUM_GROUP].Captures.Count != 0) { dayStr = match.Groups[DATE_NUM_GROUP].Value.ToLower(); if (Enum.TryParse(dayStr, true, out dayEnum) && Enum.IsDefined(typeof(MONTH_OFFSET), dayEnum)) { day = (int)dayEnum; } else { int.TryParse(dayStr, out day); } } else { dayStr = match.Groups[DATE_GROUP].Value.Trim().Replace('_', ' ').ToLower(); if (Enum.TryParse(dayStr, true, out dayEnum) && Enum.IsDefined(typeof(ORDINAL_WORDS), dayEnum)) { day = (int)dayEnum; } } string yearStr = null; int year = -1; if (match.Groups[YEAR_GROUP].Captures.Count != 0) { yearStr = match.Groups[YEAR_GROUP].Value; if (new Regex("BE", RegexOptions.IgnoreCase).Match(yearStr).Success) { // Buddhist Era yearStr = Regex.Replace(yearStr, "BE", String.Empty, RegexOptions.IgnoreCase); int.TryParse(yearStr, out year); year -= 543; } else if (new Regex("BC", RegexOptions.IgnoreCase).Match(yearStr).Success) { // Before Christ yearStr = Regex.Replace(yearStr, "BC", String.Empty, RegexOptions.IgnoreCase); int.TryParse(yearStr, out year); year *= -1; } else if (new Regex("AD", RegexOptions.IgnoreCase).Match(yearStr).Success) { yearStr = Regex.Replace(yearStr, "AD", String.Empty, RegexOptions.IgnoreCase); int.TryParse(yearStr, out year); } else { int.TryParse(yearStr, out year); if (year < 100) { year = year + 2000; } } } if (year != -1) { result.Start.Assign("day", day); result.Start.Assign("month", month); result.Start.Assign("year", year); } else { //Find the most appropriated year PredictAppropriateYear(reference, month, day, ref result); } // Weekday component if (match.Groups[WEEKDAY_GROUP].Captures.Count != 0) { var weekdayStr = match.Groups[WEEKDAY_GROUP].Value.ToLower(); WEEKDAY_OFFSET weekdayEnum; if (Enum.TryParse(weekdayStr, true, out weekdayEnum) && Enum.IsDefined(typeof(WEEKDAY_OFFSET), weekdayEnum)) { int weekday = (int)weekdayEnum; result.Start.Assign("weekday", weekday); } } // Text can be 'range' value. Such as '12 - 13 January 2012' if (match.Groups[DATE_TO_GROUP].Captures.Count != 0) { string endDateStr = match.Groups[DATE_TO_NUM_GROUP].Value; int endDate = -1; ORDINAL_WORDS endDateEnum; if (match.Groups[DATE_TO_NUM_GROUP].Captures.Count != 0) { int.TryParse(endDateStr, out endDate); } else if (Enum.TryParse(endDateStr.Trim().Replace('-', ' '), true, out endDateEnum) && Enum.IsDefined(typeof(WEEKDAY_OFFSET), endDateEnum)) { endDate = (int)endDateEnum; } result.End = (ParsedComponents)result.Start.Clone(); result.End.Assign("day", endDate); } result.Tags["ENMonthNameLittleEndianParser"] = true; return(result); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { var index = match.Index + match.Groups[1].Length; var text = match.Groups[0].Value.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length); var result = new ParsedResult(new TemporalResult { Text = text, Index = index, Reference = reference }); int month = -1; var monthStr = match.Groups[MONTH_NAME_GROUP].Value.ToLower(); MONTH_OFFSET monthEnum; if (Enum.TryParse(monthStr, true, out monthEnum) && Enum.IsDefined(typeof(MONTH_OFFSET), monthEnum)) { month = (int)monthEnum; } var day = 1; int year = -1; string yearStr = null; if (match.Groups[YEAR_GROUP].Captures.Count != 0) { yearStr = match.Groups[YEAR_GROUP].Value; int.TryParse(yearStr, out year); if (match.Groups[YEAR_BE_GROUP].Captures.Count != 0) { if (new Regex("BE", RegexOptions.IgnoreCase).IsMatch(match.Groups[YEAR_BE_GROUP].Value)) { // Buddhist Era year = year - 543; } else if (new Regex("BC", RegexOptions.IgnoreCase).IsMatch(match.Groups[YEAR_BE_GROUP].Value)) { // Before Christ year = -year; } } else if (year < 100) { year = year + 2000; } } if (year != -1) { result.Start.Imply("day", day); result.Start.Assign("month", month); result.Start.Assign("year", year); } else { //Find the most appropriated year PredictAppropriateYear(reference, month, day, ref result); } result.Tags["ENMonthNameParser"] = true; return(result); }
protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt) { if (match.Index > 0 && new Regex(@"/\w/").Match(originalText[match.Index - 1].ToString()).Success) { return(null); } var text = match.Groups[0].Value; text = text.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length); int index = match.Index + match.Groups[1].Length; var result = new ParsedResult(new TemporalResult { Text = text, Index = index, Reference = reference }); var fragments = Util.ExtractDateTimeUnitFragments(match.Groups[2].Value); var date = new DateTime(reference.Value.Year, reference.Value.Month, reference.Value.Day); foreach (var kvp in fragments) { switch (kvp.Key) { case TEMPORAL_COMPONENT.Year: date = date.AddYears(-kvp.Value); break; case TEMPORAL_COMPONENT.Month: date = date.AddMonths(-kvp.Value); break; case TEMPORAL_COMPONENT.Day: date = date.AddDays(-kvp.Value); break; case TEMPORAL_COMPONENT.Hour: date = date.AddHours(-kvp.Value); break; case TEMPORAL_COMPONENT.Minute: date = date.AddMinutes(-kvp.Value); break; case TEMPORAL_COMPONENT.Second: date = date.AddSeconds(-kvp.Value); break; case TEMPORAL_COMPONENT.Week: date = date.AddDays(-kvp.Value * 7); break; default: break; } } if ((fragments.ContainsKey(TEMPORAL_COMPONENT.Hour) && fragments[TEMPORAL_COMPONENT.Hour] > 0) || (fragments.ContainsKey(TEMPORAL_COMPONENT.Minute) && fragments[TEMPORAL_COMPONENT.Minute] > 0) || (fragments.ContainsKey(TEMPORAL_COMPONENT.Second) && fragments[TEMPORAL_COMPONENT.Second] > 0)) { result.Start.Assign("hour", date.Hour); result.Start.Assign("minute", date.Minute); result.Start.Assign("second", date.Second); result.Tags["ENTimeAgoFormatParser"] = true; } if ((fragments.ContainsKey(TEMPORAL_COMPONENT.Day) && fragments[TEMPORAL_COMPONENT.Day] > 0) || (fragments.ContainsKey(TEMPORAL_COMPONENT.Month) && fragments[TEMPORAL_COMPONENT.Month] > 0) || (fragments.ContainsKey(TEMPORAL_COMPONENT.Year) && fragments[TEMPORAL_COMPONENT.Year] > 0)) { result.Start.Assign("day", date.Day); result.Start.Assign("month", date.Month); result.Start.Assign("year", date.Year); } else { if (fragments.ContainsKey(TEMPORAL_COMPONENT.Week) && fragments[TEMPORAL_COMPONENT.Week] > 0) { result.Start.Imply("weekday", date.Day); } result.Start.Imply("day", date.Day); result.Start.Imply("month", date.Month); result.Start.Imply("year", date.Year); } return(result); }