// Cases like "3 days from today", "5 weeks before yesterday", "2 months after tomorrow" // Note that these cases are of type "date" private List <Token> ExtractRelativeDurationDate(string text, DateObject reference) { var ret = new List <Token>(); var durationEr = config.DurationExtractor.Extract(text, reference); foreach (var er in durationEr) { // if it is a multiple duration but its type is not equal to Date, skip it here if (IsMultipleDuration(er) && !IsMultipleDurationDate(er)) { continue; } // Some types of duration can be compounded with "before", "after" or "from" suffix to create a "date" // While some other types of durations, when compounded with such suffix, it will not create a "date", but create a "dateperiod" // For example, durations like "3 days", "2 weeks", "1 week and 2 days", can be compounded with such suffix to create a "date" // But "more than 3 days", "less than 2 weeks", when compounded with such suffix, it will become cases like "more than 3 days from today" which is a "dateperiod", not a "date" // As this parent method is aimed to extract RelativeDurationDate, so for cases with "more than" or "less than", we remove the prefix so as to extract the expected RelativeDurationDate if (IsInequalityDuration(er)) { StripInequalityDuration(er); } var match = config.DateUnitRegex.Match(er.Text); if (match.Success) { ret = AgoLaterUtil.ExtractorDurationWithBeforeAndAfter(text, er, ret, config.UtilityConfiguration); } } return(ret); }
// Process case like "two minutes ago" "three hours later" private List <Token> DurationWithBeforeAndAfter(string text, DateObject reference) { var ret = new List <Token>(); var durationEr = config.DurationExtractor.Extract(text, reference); foreach (var er in durationEr) { // if it is a multiple duration and its type is equal to Date than skip it. if (er.Data != null && er.Data.ToString() == Constants.MultipleDuration_Date) { continue; } var match = config.UnitRegex.Match(er.Text); if (!match.Success) { continue; } ret = AgoLaterUtil.ExtractorDurationWithBeforeAndAfter(text, er, ret, config.UtilityConfiguration); } return(ret); }
// Handle cases like "two days ago" private DateTimeResolutionResult ParseDurationWithAgoAndLater(string text, DateObject referenceDate) { return AgoLaterUtil.ParseDurationWithAgoAndLater(text, referenceDate, config.DurationExtractor, config.DurationParser, config.UnitMap, config.UnitRegex, config.UtilityConfiguration); }
// Handle cases like "two hours ago" private DateTimeResolutionResult ParserDurationWithAgoAndLater(string text, DateObject referenceTime) { return(AgoLaterUtil.ParseDurationWithAgoAndLater( text, referenceTime, config.DurationExtractor, config.DurationParser, config.NumberParser, config.UnitMap, config.UnitRegex, config.UtilityConfiguration, config.GetSwiftDay)); }
// handle like "two days ago" private DateTimeResolutionResult ParserDurationWithAgoAndLater(string text, DateObject referenceDate) { return(AgoLaterUtil.ParserDurationWithAgoAndLater( text, referenceDate, config.DurationExtractor, config.CardinalExtractor, config.NumberParser, config.UnitMap, config.UnitRegex, config.UtilityConfiguration, AgoLaterUtil.AgoLaterMode.Date )); }
private List<Token> DurationWithBeforeAndAfter(string text, DateObject reference) { var ret = new List<Token>(); var durationEr = config.DurationExtractor.Extract(text, reference); foreach (var er in durationEr) { var match = config.DateUnitRegex.Match(er.Text); if (match.Success) { ret = AgoLaterUtil.ExtractorDurationWithBeforeAndAfter(text, er, ret, config.UtilityConfiguration); } } return ret; }
// process case like "two minutes ago" "three hours later" private List <Token> DurationWithBeforeAndAfter(string text) { var ret = new List <Token>(); var durationEr = config.DurationExtractor.Extract(text); foreach (var er in durationEr) { var match = config.UnitRegex.Match(er.Text); if (!match.Success) { continue; } ret = AgoLaterUtil.ExtractorDurationWithBeforeAndAfter(text, er, ret, config.UtilityConfiguration); } return(ret); }
// Cases like "3 days from today", "5 weeks before yesterday", "2 months after tomorrow" // Note that these cases are of type "date" private List <Token> ExtractRelativeDurationDate(string text, List <Token> tokens, DateObject reference) { var ret = new List <Token>(); var tempTokens = new List <Token>(tokens); var durationEr = Config.DurationExtractor.Extract(text, reference); foreach (var er in durationEr) { // if it is a multiple duration but its type is not equal to Date, skip it here if (IsMultipleDuration(er) && !IsMultipleDurationDate(er)) { continue; } // Some types of duration can be compounded with "before", "after" or "from" suffix to create a "date" // While some other types of durations, when compounded with such suffix, it will not create a "date", but create a "dateperiod" // For example, durations like "3 days", "2 weeks", "1 week and 2 days", can be compounded with such suffix to create a "date" // But "more than 3 days", "less than 2 weeks", when compounded with such suffix, it will become cases like "more than 3 days from today" which is a "dateperiod", not a "date" // As this parent method is aimed to extract RelativeDurationDate, so for cases with "more than" or "less than", we remove the prefix so as to extract the expected RelativeDurationDate if (IsInequalityDuration(er)) { StripInequalityDuration(er); } var match = Config.DateUnitRegex.Match(er.Text); if (match.Success) { ret.AddRange(AgoLaterUtil.ExtractorDurationWithBeforeAndAfter(text, er, ret, Config.UtilityConfiguration)); // Take into account also holiday dates if (ret.Count < 1) { var holidayEr = Config.HolidayExtractor.Extract(text, reference); foreach (var holiday in holidayEr) { tempTokens.Add(new Token((int)holiday.Start, (int)(holiday.Start + holiday.Length))); } } // Check for combined patterns Duration + Date, e.g. '3 days before Monday', '4 weeks after January 15th' if (ret.Count < 1 && tempTokens.Count > 0 && er.Text != match.Value) { var afterStr = text.Substring((int)er.Start + (int)er.Length); var connector = Config.BeforeAfterRegex.MatchBegin(afterStr, trim: true); if (connector.Success) { foreach (var token in tempTokens) { var start = (int)er.Start + (int)er.Length + connector.Index + connector.Length; var length = token.Start - start; if (length > 0 && start + length < text.Length && string.IsNullOrWhiteSpace(text.Substring(start, length))) { Token tok = new Token((int)er.Start, token.End); ret.Add(tok); } } } } } } // Extract cases like "in 3 weeks", which equals to "3 weeks from today" var relativeDurationDateWithInPrefix = ExtractRelativeDurationDateWithInPrefix(text, durationEr, reference); // For cases like "in 3 weeks from today", we should choose "3 weeks from today" as the extract result rather than "in 3 weeks" or "in 3 weeks from today" foreach (var extractResultWithInPrefix in relativeDurationDateWithInPrefix) { if (!IsOverlapWithExistExtractions(extractResultWithInPrefix, ret)) { ret.Add(extractResultWithInPrefix); } } // Extend extraction with weekdays like in "Friday two weeks from now", "in 3 weeks on Monday" ret.AddRange(ExtendWithWeekDay(ret, text)); return(ret); }