Beispiel #1
0
        //TODO: this can be abstracted with the similar method in BaseDatePeriodParser
        // Parse "in 20 minutes"
        private DateTimeResolutionResult ParseDuration(string text, DateObject referenceTime)
        {
            var ret = new DateTimeResolutionResult();

            // For the rest of datetime, it will be handled in next function
            if (Config.RestOfDateTimeRegex.IsMatch(text))
            {
                return(ret);
            }

            var ers = Config.DurationExtractor.Extract(text, referenceTime);

            if (ers.Count == 1)
            {
                var pr = Config.DurationParser.Parse(ers[0]);

                var beforeStr = text.Substring(0, pr.Start ?? 0).Trim().ToLowerInvariant();
                var afterStr  = text.Substring((pr.Start ?? 0) + (pr.Length ?? 0)).Trim().ToLowerInvariant();

                if (pr.Value != null)
                {
                    var swiftSeconds   = 0;
                    var mod            = "";
                    var durationResult = (DateTimeResolutionResult)pr.Value;
                    if (durationResult.PastValue is double && durationResult.FutureValue is double)
                    {
                        swiftSeconds = (int)((double)durationResult.FutureValue);
                    }

                    DateObject beginTime;
                    var        endTime = beginTime = referenceTime;

                    var prefixMatch = Config.PastRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        mod       = Constants.BEFORE_MOD;
                        beginTime = referenceTime.AddSeconds(-swiftSeconds);
                    }

                    // Handle the "within (the) (next) xx seconds/minutes/hours" case
                    // Should also handle the multiple duration case like P1DT8H
                    // Set the beginTime equal to reference time for now
                    prefixMatch = Config.WithinNextPrefixRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        endTime = beginTime.AddSeconds(swiftSeconds);
                    }

                    prefixMatch = Config.FutureRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        mod     = Constants.AFTER_MOD;
                        endTime = beginTime.AddSeconds(swiftSeconds);
                    }

                    var suffixMatch = Config.PastRegex.Match(afterStr);
                    if (suffixMatch.Success && suffixMatch.Length == afterStr.Length)
                    {
                        mod       = Constants.BEFORE_MOD;
                        beginTime = referenceTime.AddSeconds(-swiftSeconds);
                    }

                    suffixMatch = Config.FutureRegex.Match(afterStr);
                    if (suffixMatch.Success && suffixMatch.Length == afterStr.Length)
                    {
                        mod     = Constants.AFTER_MOD;
                        endTime = beginTime.AddSeconds(swiftSeconds);
                    }

                    suffixMatch = Config.FutureSuffixRegex.Match(afterStr);
                    if (suffixMatch.Success && suffixMatch.Length == afterStr.Length)
                    {
                        mod     = Constants.AFTER_MOD;
                        endTime = beginTime.AddSeconds(swiftSeconds);
                    }

                    ret.Timex =
                        $"({FormatUtil.LuisDate(beginTime)}T{FormatUtil.LuisTime(beginTime)}," +
                        $"{FormatUtil.LuisDate(endTime)}T{FormatUtil.LuisTime(endTime)}," +
                        $"{durationResult.Timex})";

                    ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(beginTime, endTime);
                    ret.Success     = true;

                    if (!string.IsNullOrEmpty(mod))
                    {
                        ((DateTimeResolutionResult)pr.Value).Mod = mod;
                    }

                    ret.SubDateTimeEntities = new List <object> {
                        pr
                    };

                    return(ret);
                }
            }

            return(ret);
        }
        // Parse "last minute", "next hour"
        private DateTimeResolutionResult ParseRelativeUnit(string text, DateObject referenceTime)
        {
            var ret = new DateTimeResolutionResult();

            var match = Config.RelativeTimeUnitRegex.Match(text);

            if (!match.Success)
            {
                match = this.Config.RestOfDateTimeRegex.Match(text);
            }

            if (match.Success)
            {
                var srcUnit = match.Groups["unit"].Value.ToLower();

                var unitStr = Config.UnitMap[srcUnit];

                int swiftValue  = 1;
                var prefixMatch = Config.PastRegex.Match(text);
                if (prefixMatch.Success)
                {
                    swiftValue = -1;
                }

                DateObject beginTime;
                var        endTime = beginTime = referenceTime;
                var        ptTimex = string.Empty;

                if (Config.UnitMap.ContainsKey(srcUnit))
                {
                    switch (unitStr)
                    {
                    case "D":
                        endTime = DateObject.MinValue.SafeCreateFromValue(beginTime.Year, beginTime.Month, beginTime.Day);
                        endTime = endTime.AddDays(1).AddSeconds(-1);
                        ptTimex = "PT" + (endTime - beginTime).TotalSeconds + "S";
                        break;

                    case "H":
                        beginTime = swiftValue > 0 ? beginTime : referenceTime.AddHours(swiftValue);
                        endTime   = swiftValue > 0 ? referenceTime.AddHours(swiftValue) : endTime;
                        ptTimex   = "PT1H";
                        break;

                    case "M":
                        beginTime = swiftValue > 0 ? beginTime : referenceTime.AddMinutes(swiftValue);
                        endTime   = swiftValue > 0 ? referenceTime.AddMinutes(swiftValue) : endTime;
                        ptTimex   = "PT1M";
                        break;

                    case "S":
                        beginTime = swiftValue > 0 ? beginTime : referenceTime.AddSeconds(swiftValue);
                        endTime   = swiftValue > 0 ? referenceTime.AddSeconds(swiftValue) : endTime;
                        ptTimex   = "PT1S";
                        break;

                    default:
                        return(ret);
                    }

                    ret.Timex =
                        $"({FormatUtil.LuisDate(beginTime)}T{FormatUtil.LuisTime(beginTime)}," +
                        $"{FormatUtil.LuisDate(endTime)}T{FormatUtil.LuisTime(endTime)},{ptTimex})";

                    ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(beginTime, endTime);
                    ret.Success     = true;

                    return(ret);
                }
            }

            return(ret);
        }
        //TODO: this can be abstracted with the similar method in BaseDatePeriodParser
        // parse "in 20 minutes"
        private DateTimeResolutionResult ParseDuration(string text, DateObject referenceTime)
        {
            var ret = new DateTimeResolutionResult();

            //for rest of datetime, it will be handled in next function
            if (Config.RestOfDateTimeRegex.IsMatch(text))
            {
                return(ret);
            }

            var ers = Config.DurationExtractor.Extract(text);

            if (ers.Count == 1)
            {
                var pr        = Config.DurationParser.Parse(ers[0]);
                var beforeStr = text.Substring(0, pr.Start ?? 0).Trim().ToLowerInvariant();
                if (pr.Value != null)
                {
                    var swiftSeconds   = 0;
                    var mod            = "";
                    var durationResult = (DateTimeResolutionResult)pr.Value;
                    if (durationResult.PastValue is double && durationResult.FutureValue is double)
                    {
                        swiftSeconds = (int)((double)durationResult.FutureValue);
                    }

                    DateObject beginTime;
                    var        endTime = beginTime = referenceTime;

                    var prefixMatch = Config.PastRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        mod       = TimeTypeConstants.beforeMod;
                        beginTime = referenceTime.AddSeconds(-swiftSeconds);
                    }

                    prefixMatch = Config.FutureRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        mod     = TimeTypeConstants.afterMod;
                        endTime = beginTime.AddSeconds(swiftSeconds);
                    }

                    ret.Timex =
                        $"({FormatUtil.LuisDate(beginTime)}T{FormatUtil.LuisTime(beginTime)}," +
                        $"{FormatUtil.LuisDate(endTime)}T{FormatUtil.LuisTime(endTime)}," +
                        $"{durationResult.Timex})";
                    ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(beginTime, endTime);
                    ret.Success     = true;

                    if (!string.IsNullOrEmpty(mod))
                    {
                        ((DateTimeResolutionResult)pr.Value).Mod = mod;
                    }
                    ret.SubDateTimeEntities = new List <object> {
                        pr
                    };

                    return(ret);
                }
            }

            return(ret);
        }