// merge the entity with its related contexts and then parse the combine text private static DateTimeResolutionResult GetResolution(ExtractResult er, DateTimeParseResult pr, DateTimeResolutionResult ret) { var parentText = (string)((Dictionary <string, object>)er.Data)[ExtendedModelResult.ParentTextKey]; var type = pr.Type; var singlePointResolution = string.Empty; var pastStartPointResolution = string.Empty; var pastEndPointResolution = string.Empty; var futureStartPointResolution = string.Empty; var futureEndPointResolution = string.Empty; var singlePointType = string.Empty; var startPointType = string.Empty; var endPointType = string.Empty; if (type is Constants.SYS_DATETIME_DATEPERIOD or Constants.SYS_DATETIME_TIMEPERIOD or Constants.SYS_DATETIME_DATETIMEPERIOD) { switch (type) { case Constants.SYS_DATETIME_DATEPERIOD: startPointType = TimeTypeConstants.START_DATE; endPointType = TimeTypeConstants.END_DATE; pastStartPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.PastValue).Item1); pastEndPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.PastValue).Item2); futureStartPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.FutureValue).Item1); futureEndPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.FutureValue).Item2); break; case Constants.SYS_DATETIME_DATETIMEPERIOD: startPointType = TimeTypeConstants.START_DATETIME; endPointType = TimeTypeConstants.END_DATETIME; if (ret.PastValue is Tuple <DateObject, DateObject> tuple) { pastStartPointResolution = DateTimeFormatUtil.FormatDateTime(tuple.Item1); pastEndPointResolution = DateTimeFormatUtil.FormatDateTime(tuple.Item2); futureStartPointResolution = DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item1); futureEndPointResolution = DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item2); } else if (ret.PastValue is DateObject datetime) { pastStartPointResolution = DateTimeFormatUtil.FormatDateTime(datetime); futureStartPointResolution = DateTimeFormatUtil.FormatDateTime((DateObject)ret.FutureValue); } break; case Constants.SYS_DATETIME_TIMEPERIOD: startPointType = TimeTypeConstants.START_TIME; endPointType = TimeTypeConstants.END_TIME; pastStartPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.PastValue).Item1); pastEndPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.PastValue).Item2); futureStartPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item1); futureEndPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item2); break; } }
private DateTimeResolutionResult ParseTimeOfToday(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); var ers = this.config.TimeExtractor.Extract(text, referenceTime); if (ers.Count != 1) { return(ret); } // TODO: Add reference time var pr = this.config.TimeParser.Parse(ers[0], referenceTime); if (pr.Value is null) { return(ret); } var time = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue; var hour = time.Hour; var min = time.Minute; var sec = time.Second; var match = this.config.TimeOfTodayRegex.Match(text); if (match.Success) { var matchStr = match.Value; var swift = 0; this.config.AdjustByTimeOfDay(matchStr, ref hour, ref swift); var date = referenceTime.AddDays(swift).Date; // in this situation, luisStr cannot end up with "ampm", because we always have a "morning" or "night" var timeStr = pr.TimexStr; if (timeStr.EndsWith(Constants.Comment_AmPm, StringComparison.Ordinal)) { timeStr = timeStr.Substring(0, timeStr.Length - 4); } timeStr = "T" + hour.ToString("D2", CultureInfo.InvariantCulture) + timeStr.Substring(3); ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = DateObject.MinValue.SafeCreateFromValue(date.Year, date.Month, date.Day, hour, min, sec); ret.Success = true; return(ret); } return(ret); }
private DateTimeResolutionResult ParseUnspecificTimeOfDate(string text, DateObject refDateTime) { // Handle 'eod', 'end of day' var ret = new DateTimeResolutionResult(); var eod = this.config.UnspecificEndOfRegex.Match(text); if (eod.Success) { ret = DateTimeFormatUtil.ResolveEndOfDay(DateTimeFormatUtil.FormatDate(refDateTime), refDateTime, refDateTime); } return(ret); }
public DateTimeParseResult Parse(ExtractResult er, DateObject refDate) { var referenceDate = refDate; object value = null; if (er.Type.Equals(ParserName, StringComparison.Ordinal)) { var innerResult = ParseHolidayRegexMatch(er.Text, referenceDate); if (innerResult.Success) { innerResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.DATE, DateTimeFormatUtil.FormatDate((DateObject)innerResult.FutureValue) }, }; innerResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.DATE, DateTimeFormatUtil.FormatDate((DateObject)innerResult.PastValue) }, }; innerResult.IsLunar = IsLunarCalendar(er.Text); value = innerResult; } } var ret = new DateTimeParseResult { Text = er.Text, Start = er.Start, Length = er.Length, Type = er.Type, Data = er.Data, Value = value, TimexStr = value == null ? string.Empty : ((DateTimeResolutionResult)value).Timex, ResolutionStr = string.Empty, }; return(ret); }
protected DateTimeResolutionResult InnerParser(string text, DateObject reference) { var innerResult = ParseBasicRegexMatch(text, reference); if (!innerResult.Success) { innerResult = ParseImplicitDate(text, reference); } if (!innerResult.Success) { innerResult = ParseWeekdayOfMonth(text, reference); } if (!innerResult.Success) { innerResult = ParserDurationWithAgoAndLater(text, reference); } if (innerResult.Success) { innerResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.DATE, DateTimeFormatUtil.FormatDate((DateObject)innerResult.FutureValue) }, }; innerResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.DATE, DateTimeFormatUtil.FormatDate((DateObject)innerResult.PastValue) }, }; innerResult.IsLunar = IsLunarCalendar(text); return(innerResult); } return(null); }
private static DateTimeResolutionResult GetResolution(ExtractResult er, DateTimeParseResult pr, DateTimeResolutionResult ret) { var parentText = (string)((Dictionary <string, object>)er.Data)[ExtendedModelResult.ParentTextKey]; var type = pr.Type; var singlePointResolution = ""; var pastStartPointResolution = ""; var pastEndPointResolution = ""; var futureStartPointResolution = ""; var futureEndPointResolution = ""; var singlePointType = ""; var startPointType = ""; var endPointType = ""; if (type == Constants.SYS_DATETIME_DATEPERIOD || type == Constants.SYS_DATETIME_TIMEPERIOD || type == Constants.SYS_DATETIME_DATETIMEPERIOD) { switch (type) { case Constants.SYS_DATETIME_DATEPERIOD: startPointType = TimeTypeConstants.START_DATE; endPointType = TimeTypeConstants.END_DATE; pastStartPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.PastValue).Item1); pastEndPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.PastValue).Item2); futureStartPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.FutureValue).Item1); futureEndPointResolution = DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)ret.FutureValue).Item2); break; case Constants.SYS_DATETIME_DATETIMEPERIOD: startPointType = TimeTypeConstants.START_DATETIME; endPointType = TimeTypeConstants.END_DATETIME; if (ret.PastValue is Tuple <DateObject, DateObject> tuple) { pastStartPointResolution = DateTimeFormatUtil.FormatDateTime(tuple.Item1); pastEndPointResolution = DateTimeFormatUtil.FormatDateTime(tuple.Item2); futureStartPointResolution = DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item1); futureEndPointResolution = DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item2); } else if (ret.PastValue is DateObject datetime) { pastStartPointResolution = DateTimeFormatUtil.FormatDateTime(datetime); futureStartPointResolution = DateTimeFormatUtil.FormatDateTime((DateObject)ret.FutureValue); } break; case Constants.SYS_DATETIME_TIMEPERIOD: startPointType = TimeTypeConstants.START_TIME; endPointType = TimeTypeConstants.END_TIME; pastStartPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.PastValue).Item1); pastEndPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.PastValue).Item2); futureStartPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item1); futureEndPointResolution = DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)ret.FutureValue).Item2); break; } } else { switch (type) { case Constants.SYS_DATETIME_DATE: singlePointType = TimeTypeConstants.DATE; singlePointResolution = DateTimeFormatUtil.FormatDate((DateObject)ret.FutureValue); break; case Constants.SYS_DATETIME_DATETIME: singlePointType = TimeTypeConstants.DATETIME; singlePointResolution = DateTimeFormatUtil.FormatDateTime((DateObject)ret.FutureValue); break; case Constants.SYS_DATETIME_TIME: singlePointType = TimeTypeConstants.TIME; singlePointResolution = DateTimeFormatUtil.FormatTime((DateObject)ret.FutureValue); break; } } ret.FutureResolution = new Dictionary <string, string>(); ret.PastResolution = new Dictionary <string, string>(); if (!string.IsNullOrEmpty(futureStartPointResolution)) { ret.FutureResolution.Add(startPointType, futureStartPointResolution); } if (!string.IsNullOrEmpty(futureEndPointResolution)) { ret.FutureResolution.Add(endPointType, futureEndPointResolution); } if (!string.IsNullOrEmpty(pastStartPointResolution)) { ret.PastResolution.Add(startPointType, pastStartPointResolution); } if (!string.IsNullOrEmpty(pastEndPointResolution)) { ret.PastResolution.Add(endPointType, pastEndPointResolution); } if (!string.IsNullOrEmpty(singlePointResolution)) { ret.FutureResolution.Add(singlePointType, singlePointResolution); ret.PastResolution.Add(singlePointType, singlePointResolution); } if (!string.IsNullOrEmpty(parentText)) { ret.FutureResolution.Add(ExtendedModelResult.ParentTextKey, parentText); ret.PastResolution.Add(ExtendedModelResult.ParentTextKey, parentText); } if (((DateTimeResolutionResult)pr.Value).Mod != null) { ret.Mod = ((DateTimeResolutionResult)pr.Value).Mod; } if (((DateTimeResolutionResult)pr.Value).TimeZoneResolution != null) { ret.TimeZoneResolution = ((DateTimeResolutionResult)pr.Value).TimeZoneResolution; } return(ret); }
public DateTimeParseResult Parse(ExtractResult er, DateObject reference) { var referenceDate = reference; object value = null; if (er.Type.Equals(ParserName, StringComparison.Ordinal)) { var innerResult = ParseBasicRegexMatch(er.Text, referenceDate); if (!innerResult.Success) { innerResult = ParseImplicitDate(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseWeekdayOfMonth(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseDurationWithAgoAndLater(er.Text, referenceDate); } // NumberWithMonth must be the second last one, because it only need to find a number and a month to get a "success" if (!innerResult.Success) { innerResult = ParseNumberWithMonth(er.Text, referenceDate); } // SingleNumber last one if (!innerResult.Success) { innerResult = ParseSingleNumber(er.Text, referenceDate); } if (innerResult.Success) { innerResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.DATE, DateTimeFormatUtil.FormatDate((DateObject)innerResult.FutureValue) }, }; innerResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.DATE, DateTimeFormatUtil.FormatDate((DateObject)innerResult.PastValue) }, }; value = innerResult; } } var ret = new DateTimeParseResult { Text = er.Text, Start = er.Start, Length = er.Length, Type = er.Type, Data = er.Data, Value = value, TimexStr = value == null ? string.Empty : ((DateTimeResolutionResult)value).Timex, ResolutionStr = string.Empty, }; return(ret); }
// Parse specific TimeOfDay like "this night", "early morning", "late evening" protected virtual DateTimeResolutionResult ParseSpecificTimeOfDay(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); var trimmedText = text.Trim().ToLowerInvariant(); var timeText = trimmedText; var match = this.Config.PeriodTimeOfDayWithDateRegex.Match(trimmedText); // Extract early/late prefix from text if any bool hasEarly = false, hasLate = false; if (match.Success) { timeText = match.Groups[Constants.TimeOfDayGroupName].Value; if (!string.IsNullOrEmpty(match.Groups["early"].Value)) { hasEarly = true; ret.Comment = Constants.Comment_Early; } if (!hasEarly && !string.IsNullOrEmpty(match.Groups["late"].Value)) { hasLate = true; ret.Comment = Constants.Comment_Late; } } else { match = this.Config.AmDescRegex.Match(trimmedText); if (!match.Success) { match = this.Config.PmDescRegex.Match(trimmedText); } if (match.Success) { timeText = match.Value; } } // Handle time of day // Late/early only works with time of day // Only standard time of day (morning, afternoon, evening and night) will not directly return if (!this.Config.GetMatchedTimeRange(timeText, out string timeStr, out int beginHour, out int endHour, out int endMin)) { return(ret); } // Modify time period if "early" or "late" exists // Since 'time of day' is defined as four hour periods, // the first 2 hours represent early, the later 2 hours represent late if (hasEarly) { endHour = beginHour + 2; // Handling speical case: night ends with 23:59 if (endMin == 59) { endMin = 0; } } else if (hasLate) { beginHour = beginHour + 2; } if (Config.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true)) { var swift = this.Config.GetSwiftPrefix(trimmedText); var date = referenceTime.AddDays(swift).Date; int day = date.Day, month = date.Month, year = date.Year; ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(DateObject.MinValue.SafeCreateFromValue(year, month, day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(year, month, day, endHour, endMin, endMin)); ret.Success = true; return(ret); } // Handle Date followed by morning, afternoon and morning, afternoon followed by Date match = this.Config.PeriodTimeOfDayWithDateRegex.Match(trimmedText); if (!match.Success) { match = this.Config.AmDescRegex.Match(trimmedText); if (!match.Success) { match = this.Config.PmDescRegex.Match(trimmedText); } } if (match.Success) { var beforeStr = trimmedText.Substring(0, match.Index).Trim(); var afterStr = trimmedText.Substring(match.Index + match.Length).Trim(); // Eliminate time period, if any var timePeriodErs = this.Config.TimePeriodExtractor.Extract(beforeStr); if (timePeriodErs.Count > 0) { beforeStr = beforeStr.Remove(timePeriodErs[0].Start ?? 0, timePeriodErs[0].Length ?? 0).Trim(); } else { timePeriodErs = this.Config.TimePeriodExtractor.Extract(afterStr); if (timePeriodErs.Count > 0) { afterStr = afterStr.Remove(timePeriodErs[0].Start ?? 0, timePeriodErs[0].Length ?? 0).Trim(); } } var ers = this.Config.DateExtractor.Extract(beforeStr + ' ' + afterStr, referenceTime); if (ers.Count == 0 || ers[0].Length < beforeStr.Length) { var valid = false; if (ers.Count > 0 && ers[0].Start == 0) { var midStr = beforeStr.Substring(ers[0].Start + ers[0].Length ?? 0); if (string.IsNullOrWhiteSpace(midStr.Replace(',', ' '))) { valid = true; } } if (!valid) { ers = this.Config.DateExtractor.Extract(afterStr, referenceTime); if (ers.Count == 0 || ers[0].Length != afterStr.Length) { if (ers.Count > 0 && ers[0].Start + ers[0].Length == afterStr.Length) { var midStr = afterStr.Substring(0, ers[0].Start ?? 0); if (string.IsNullOrWhiteSpace(midStr.Replace(',', ' '))) { valid = true; } } } else { valid = true; } } if (!valid) { return(ret); } } var hasSpecificTimePeriod = false; if (timePeriodErs.Count > 0) { var timePr = this.Config.TimePeriodParser.Parse(timePeriodErs[0], referenceTime); if (timePr != null) { var periodFuture = (Tuple <DateObject, DateObject>)(((DateTimeResolutionResult)timePr.Value).FutureValue); var periodPast = (Tuple <DateObject, DateObject>)((DateTimeResolutionResult)timePr.Value).PastValue; if (periodFuture == periodPast) { beginHour = periodFuture.Item1.Hour; endHour = periodFuture.Item2.Hour; } else { if (periodFuture.Item1.Hour >= beginHour || periodFuture.Item2.Hour <= endHour) { beginHour = periodFuture.Item1.Hour; endHour = periodFuture.Item2.Hour; } else { beginHour = periodPast.Item1.Hour; endHour = periodPast.Item2.Hour; } } hasSpecificTimePeriod = true; } } var pr = this.Config.DateParser.Parse(ers[0], referenceTime); var futureDate = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue; var pastDate = (DateObject)((DateTimeResolutionResult)pr.Value).PastValue; if (!hasSpecificTimePeriod) { ret.Timex = pr.TimexStr + timeStr; } else { ret.Timex = string.Format("({0}T{1},{0}T{2},PT{3}H)", pr.TimexStr, beginHour, endHour, endHour - beginHour); } ret.FutureValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(futureDate.Year, futureDate.Month, futureDate.Day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(futureDate.Year, futureDate.Month, futureDate.Day, endHour, endMin, endMin)); ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(pastDate.Year, pastDate.Month, pastDate.Day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(pastDate.Year, pastDate.Month, pastDate.Day, endHour, endMin, endMin)); ret.Success = true; return(ret); } return(ret); }
private DateTimeResolutionResult ParseTimeOfToday(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); var trimmedText = text.Trim(); int hour = 0, min = 0, sec = 0; string timeStr; var wholeMatch = this.config.SimpleTimeOfTodayAfterRegex.MatchExact(trimmedText, trim: true); if (!wholeMatch.Success) { wholeMatch = this.config.SimpleTimeOfTodayBeforeRegex.MatchExact(trimmedText, trim: true); } if (wholeMatch.Success) { var hourStr = wholeMatch.Groups[Constants.HourGroupName].Value; if (string.IsNullOrEmpty(hourStr)) { hourStr = wholeMatch.Groups["hournum"].Value; hour = this.config.Numbers[hourStr]; } else { hour = int.Parse(hourStr, CultureInfo.InvariantCulture); } timeStr = "T" + hour.ToString("D2", CultureInfo.InvariantCulture); } else { var ers = this.config.TimeExtractor.Extract(trimmedText, referenceTime); if (ers.Count != 1) { var prefixToken = this.config.TokenBeforeTime; ers = this.config.TimeExtractor.Extract(prefixToken + trimmedText, referenceTime); if (ers.Count == 1) { ers[0].Start -= prefixToken.Length; } else { return(ret); } } var pr = this.config.TimeParser.Parse(ers[0], referenceTime); if (pr.Value == null) { return(ret); } // Add timezone ret.TimeZoneResolution = ((DateTimeResolutionResult)pr.Value).TimeZoneResolution; var time = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue; hour = time.Hour; min = time.Minute; sec = time.Second; timeStr = pr.TimexStr; } var match = this.config.SpecificTimeOfDayRegex.Match(trimmedText); if (match.Success) { var matchStr = match.Value; // Handle "last", "next" var swift = this.config.GetSwiftDay(matchStr); var date = referenceTime.AddDays(swift).Date; // Handle "morning", "afternoon" hour = this.config.GetHour(matchStr, hour); // In this situation, timeStr cannot end up with "ampm", because we always have a "morning" or "night" if (timeStr.EndsWith(Constants.Comment_AmPm, StringComparison.Ordinal)) { timeStr = timeStr.Substring(0, timeStr.Length - 4); } timeStr = "T" + hour.ToString("D2", CultureInfo.InvariantCulture) + timeStr.Substring(3); ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = DateObject.MinValue.SafeCreateFromValue(date.Year, date.Month, date.Day, hour, min, sec); ret.Success = true; return(ret); } return(ret); }
// Parse cases like "this night" private DateTimeResolutionResult ParseSpecificNight(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); var trimmedText = text.Trim(); int beginHour, endHour, endMin = 0; string timeStr; // Handle 昨晚 (last night),今晨 (this morning) if (this.config.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true)) { // handle the ambiguous case "ぎりぎり" [the latest possible time] var latest = this.config.SpecificTimeOfDayRegex.Match(text); if (latest.Groups[Constants.LatestGroupName].Success) { DateObject beginDate, endDate; beginDate = referenceTime.AddMinutes(-1); endDate = referenceTime; var diff = endDate - beginDate; ret.Timex = TimexUtility.GenerateDateTimePeriodTimex(beginDate, endDate); ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(beginDate, endDate); ret.Success = true; return(ret); } if (!this.config.GetMatchedTimeRangeAndSwift(trimmedText, out timeStr, out beginHour, out endHour, out endMin, out int swift)) { return(ret); } if (this.config.NextRegex.IsMatch(trimmedText)) { swift = 1; } else if (this.config.LastRegex.IsMatch(trimmedText)) { swift = -1; } var date = referenceTime.AddDays(swift).Date; int day = date.Day, month = date.Month, year = date.Year; ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(year, month, day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(year, month, day, endHour, endMin, endMin)); ret.Success = true; return(ret); } // Handle cases like morning, afternoon if (!this.config.GetMatchedTimeRange(trimmedText, out timeStr, out beginHour, out endHour, out endMin)) { return(ret); } if (this.config.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true)) { var swift = 0; if (this.config.NextRegex.IsMatch(trimmedText)) { swift = 1; } else if (this.config.LastRegex.IsMatch(trimmedText)) { swift = -1; } var date = referenceTime.AddDays(swift).Date; int day = date.Day, month = date.Month, year = date.Year; ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(year, month, day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(year, month, day, endHour, endMin, endMin)); ret.Success = true; return(ret); } // handle Date followed by morning, afternoon var match = this.config.TimeOfDayRegex.Match(trimmedText); if (match.Success) { var beforeStr = trimmedText.Substring(0, match.Index).Trim(); var ers = this.config.DateExtractor.Extract(beforeStr, referenceTime); if (ers.Count == 0 || ers[0].Length != beforeStr.Length) { return(ret); } var pr = this.config.DateParser.Parse(ers[0], referenceTime); var futureDate = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue; var pastDate = (DateObject)((DateTimeResolutionResult)pr.Value).PastValue; ret.Timex = pr.TimexStr + timeStr; ret.FutureValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(futureDate.Year, futureDate.Month, futureDate.Day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(futureDate.Year, futureDate.Month, futureDate.Day, endHour, endMin, endMin)); ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(pastDate.Year, pastDate.Month, pastDate.Day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(pastDate.Year, pastDate.Month, pastDate.Day, endHour, endMin, endMin)); ret.Success = true; return(ret); } return(ret); }
private DateTimeResolutionResult ParseTimeOfSpecialDayRegex(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); var ers = this.config.TimeExtractor.Extract(text, referenceTime); // Handle 'eod', 'end of day' var eod = this.config.TimeOfSpecialDayRegex.Match(text); if (eod.Groups[Constants.SpecificEndOfGroupName].Success && ers.Count == 0) { ret = ParseSpecialTimeOfDate(text, referenceTime); return(ret); } if (eod.Success && ers.Count != 1) { ret = DateTimeFormatUtil.ResolveEndOfDay(DateTimeFormatUtil.FormatDate(referenceTime), referenceTime, referenceTime); return(ret); } if (ers.Count != 1) { return(ret); } // TODO: Add reference time var pr = this.config.TimeParser.Parse(ers[0], referenceTime); if (pr.Value == null) { return(ret); } var time = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue; var hour = time.Hour; var min = time.Minute; var sec = time.Second; var match = this.config.TimeOfSpecialDayRegex.Match(text); if (match.Success) { var matchStr = match.Value; var swift = 0; this.config.AdjustByTimeOfDay(matchStr, ref hour, ref swift); var date = referenceTime.AddDays(swift).Date; // in this situation, luisStr cannot end up with "ampm", because we always have a "morning" or "night" var timeStr = pr.TimexStr; if (timeStr.EndsWith(Constants.Comment_AmPm, StringComparison.Ordinal)) { timeStr = timeStr.Substring(0, timeStr.Length - 4); } // handle less and more mode if (match.Groups[Constants.LessGroupName].Success) { ret.Mod = Constants.LESS_THAN_MOD; } else if (match.Groups[Constants.MoreGroupName].Success) { ret.Mod = Constants.MORE_THAN_MOD; } timeStr = "T" + hour.ToString("D2", CultureInfo.InvariantCulture) + timeStr.Substring(3); ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = DateObject.MinValue.SafeCreateFromValue(date.Year, date.Month, date.Day, hour, min, sec); ret.Success = true; return(ret); } return(ret); }
// This will parse to a date ranging between the holiday and the closest weekend // cases: "Thanksgiving weekend", "weekend of Halloween" private DateTimeParseResult ParseHolidayWeekend(ExtractResult er, DateObject referenceDate) { var dateTimeRes = new DateTimeResolutionResult(); if (!string.IsNullOrEmpty(er.Metadata?.HolidayName)) { var holidayName = er.Metadata.HolidayName; // resolve holiday var holidayEr = new ExtractResult { Start = 0, Length = holidayName.Length, Text = holidayName, Type = Constants.SYS_DATETIME_DATE, Data = null, Metadata = new Metadata { IsHoliday = true }, }; var result = (DateTimeResolutionResult)this.Parse(holidayEr, referenceDate).Value; if (!result.Success) { dateTimeRes.FutureResolution = dateTimeRes.PastResolution = new Dictionary <string, string>(); } else { // get closest weekend to the holiday(s) var futureWeekend = GetClosestHolidayWeekend((DateObject)result.FutureValue); var pastWeekend = futureWeekend; if (result.FutureValue == result.PastValue) { dateTimeRes.Timex = TimexUtility.GenerateWeekendTimex(futureWeekend.Item1); } else { dateTimeRes.Timex = result.Timex; pastWeekend = GetClosestHolidayWeekend((DateObject)result.PastValue); } dateTimeRes.Success = true; dateTimeRes.FutureValue = futureWeekend; dateTimeRes.PastValue = pastWeekend; dateTimeRes.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.START_DATE, DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)dateTimeRes.FutureValue).Item1) }, { TimeTypeConstants.END_DATE, DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)dateTimeRes.FutureValue).Item2) }, { DateTimeResolutionKey.Timex, TimexUtility.GenerateWeekendTimex(futureWeekend.Item1) }, }; dateTimeRes.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.START_DATE, DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)dateTimeRes.PastValue).Item1) }, { TimeTypeConstants.END_DATE, DateTimeFormatUtil.FormatDate(((Tuple <DateObject, DateObject>)dateTimeRes.PastValue).Item2) }, { DateTimeResolutionKey.Timex, TimexUtility.GenerateWeekendTimex(pastWeekend.Item1) }, }; } } else { dateTimeRes.FutureResolution = dateTimeRes.PastResolution = new Dictionary <string, string>(); } var ret = new DateTimeParseResult { Text = er.Text, Start = er.Start, Length = er.Length, Type = er.Type, Data = er.Data, Metadata = er.Metadata, Value = dateTimeRes, TimexStr = dateTimeRes == null ? string.Empty : ((DateTimeResolutionResult)dateTimeRes).Timex, ResolutionStr = string.Empty, }; return(ret); }
// parse "this night" private DateTimeResolutionResult ParseSpecificNight(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); var trimmedText = text.Trim(); int beginHour, endHour, endMin = 0; string timeStr; // handle 昨晚,今晨 if (this.config.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true)) { if (!this.config.GetMatchedTimeRangeAndSwift(trimmedText, out timeStr, out beginHour, out endHour, out int swift)) { return(ret); } var date = referenceTime.AddDays(swift).Date; int day = date.Day, month = date.Month, year = date.Year; ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(year, month, day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(year, month, day, endHour, endMin, endMin)); ret.Success = true; return(ret); } // handle morning, afternoon.. if (!this.config.GetMatchedTimeRange(trimmedText, out timeStr, out beginHour, out endHour, out endMin)) { return(ret); } if (this.config.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true)) { var swift = 0; if (this.config.NextRegex.IsMatch(trimmedText)) { swift = 1; } else if (this.config.LastRegex.IsMatch(trimmedText)) { swift = -1; } var date = referenceTime.AddDays(swift).Date; int day = date.Day, month = date.Month, year = date.Year; ret.Timex = DateTimeFormatUtil.FormatDate(date) + timeStr; ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(year, month, day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(year, month, day, endHour, endMin, endMin)); ret.Success = true; return(ret); } // handle Date followed by morning, afternoon var match = this.config.TimeOfDayRegex.Match(trimmedText); if (match.Success) { var beforeStr = trimmedText.Substring(0, match.Index).Trim(); var ers = this.config.DateExtractor.Extract(beforeStr, referenceTime); if (ers.Count == 0 || ers[0].Length != beforeStr.Length) { return(ret); } var pr = this.config.DateParser.Parse(ers[0], referenceTime); var futureDate = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue; var pastDate = (DateObject)((DateTimeResolutionResult)pr.Value).PastValue; ret.Timex = pr.TimexStr + timeStr; ret.FutureValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(futureDate.Year, futureDate.Month, futureDate.Day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(futureDate.Year, futureDate.Month, futureDate.Day, endHour, endMin, endMin)); ret.PastValue = new Tuple <DateObject, DateObject>( DateObject.MinValue.SafeCreateFromValue(pastDate.Year, pastDate.Month, pastDate.Day, beginHour, 0, 0), DateObject.MinValue.SafeCreateFromValue(pastDate.Year, pastDate.Month, pastDate.Day, endHour, endMin, endMin)); ret.Success = true; return(ret); } return(ret); }