// 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);
        }
Beispiel #4
0
 // 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));
 }
Beispiel #5
0
 // 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);
        }