//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); }