private DateTimeResolutionResult MergeTwoTimePoints(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); DateTimeParseResult pr1 = null, pr2 = null; bool bothHaveDates = false, beginHasDate = false, endHasDate = false; var er1 = SingleTimeExtractor.Extract(text, referenceTime); var er2 = TimeWithDateExtractor.Extract(text, referenceTime); var rightTime = DateObject.MinValue.SafeCreateFromValue(referenceTime.Year, referenceTime.Month, referenceTime.Day); var leftTime = DateObject.MinValue.SafeCreateFromValue(referenceTime.Year, referenceTime.Month, referenceTime.Day); if (er2.Count == 2) { pr1 = this.config.DateTimeParser.Parse(er2[0], referenceTime); pr2 = this.config.DateTimeParser.Parse(er2[1], referenceTime); bothHaveDates = true; } else if (er2.Count == 1 && er1.Count == 2) { if (!er2[0].IsOverlap(er1[0])) { pr1 = this.config.TimeParser.Parse(er1[0], referenceTime); pr2 = this.config.DateTimeParser.Parse(er2[0], referenceTime); endHasDate = true; } else { pr1 = this.config.DateTimeParser.Parse(er2[0], referenceTime); pr2 = this.config.TimeParser.Parse(er1[1], referenceTime); beginHasDate = true; } } else if (er2.Count == 1 && er1.Count == 1) { if (er1[0].Start < er2[0].Start) { pr1 = this.config.TimeParser.Parse(er1[0], referenceTime); pr2 = this.config.DateTimeParser.Parse(er2[0], referenceTime); endHasDate = true; } else { pr1 = this.config.DateTimeParser.Parse(er2[0], referenceTime); pr2 = this.config.TimeParser.Parse(er1[0], referenceTime); beginHasDate = true; } } else if (er1.Count == 2) { // if both ends are Time. then this is a TimePeriod, not a DateTimePeriod return(ret); } else { return(ret); } if (pr1.Value == null || pr2.Value == null) { return(ret); } DateObject futureBegin = (DateObject)((DateTimeResolutionResult)pr1.Value).FutureValue, futureEnd = (DateObject)((DateTimeResolutionResult)pr2.Value).FutureValue; DateObject pastBegin = (DateObject)((DateTimeResolutionResult)pr1.Value).PastValue, pastEnd = (DateObject)((DateTimeResolutionResult)pr2.Value).PastValue; if (futureBegin > futureEnd) { futureBegin = pastBegin; } if (pastEnd < pastBegin) { pastEnd = futureEnd; } if (bothHaveDates) { rightTime = DateObject.MinValue.SafeCreateFromValue(futureEnd.Year, futureEnd.Month, futureEnd.Day); leftTime = DateObject.MinValue.SafeCreateFromValue(futureBegin.Year, futureBegin.Month, futureBegin.Day); } else if (beginHasDate) { // TODO: Handle "明天下午两点到五点" futureEnd = DateObject.MinValue.SafeCreateFromValue(futureBegin.Year, futureBegin.Month, futureBegin.Day, futureEnd.Hour, futureEnd.Minute, futureEnd.Second); pastEnd = DateObject.MinValue.SafeCreateFromValue(pastBegin.Year, pastBegin.Month, pastBegin.Day, pastEnd.Hour, pastEnd.Minute, pastEnd.Second); leftTime = DateObject.MinValue.SafeCreateFromValue(futureBegin.Year, futureBegin.Month, futureBegin.Day); } else if (endHasDate) { // TODO: Handle "明天下午两点到五点" futureBegin = DateObject.MinValue.SafeCreateFromValue(futureEnd.Year, futureEnd.Month, futureEnd.Day, futureBegin.Hour, futureBegin.Minute, futureBegin.Second); pastBegin = DateObject.MinValue.SafeCreateFromValue(pastEnd.Year, pastEnd.Month, pastEnd.Day, pastBegin.Hour, pastBegin.Minute, pastBegin.Second); rightTime = DateObject.MinValue.SafeCreateFromValue(futureEnd.Year, futureEnd.Month, futureEnd.Day); } var leftResult = (DateTimeResolutionResult)pr1.Value; var rightResult = (DateTimeResolutionResult)pr2.Value; var leftResultTime = (DateObject)leftResult.FutureValue; var rightResultTime = (DateObject)rightResult.FutureValue; int day = referenceTime.Day, month = referenceTime.Month, year = referenceTime.Year; //check if the right time is smaller than the left time, if yes, add one day int hour = leftResultTime.Hour > 0 ? leftResultTime.Hour : 0, min = leftResultTime.Minute > 0 ? leftResultTime.Minute : 0, second = leftResultTime.Second > 0 ? leftResultTime.Second : 0; leftTime = leftTime.AddHours(hour); leftTime = leftTime.AddMinutes(min); leftTime = leftTime.AddSeconds(second); DateObject.MinValue.SafeCreateFromValue(year, month, day, hour, min, second); hour = rightResultTime.Hour > 0 ? rightResultTime.Hour : 0; min = rightResultTime.Minute > 0 ? rightResultTime.Minute : 0; second = rightResultTime.Second > 0 ? rightResultTime.Second : 0; rightTime = rightTime.AddHours(hour); rightTime = rightTime.AddMinutes(min); rightTime = rightTime.AddSeconds(second); //the right side time contains "ampm", while the left side doesn't if (rightResult.Comment != null && rightResult.Comment.Equals("ampm") && leftResult.Comment == null && rightTime < leftTime) { rightTime = rightTime.AddHours(12); } if (rightTime < leftTime) { rightTime = rightTime.AddDays(1); } ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(leftTime, rightTime); var leftTimex = ""; var rightTimex = ""; //"X" is timex token for not determined time if (!pr1.TimexStr.Contains("X") && !pr2.TimexStr.Contains("X")) { leftTimex = FormatUtil.LuisDateTime(leftTime); rightTimex = FormatUtil.LuisDateTime(rightTime); } else { leftTimex = pr1.TimexStr; rightTimex = pr2.TimexStr; } ret.Timex = $"({leftTimex},{rightTimex},PT{Convert.ToInt32((rightTime - leftTime).TotalHours)}H)"; ret.Success = true; return(ret); }
public ParseResult Parse(ExtractResult er, DateObject?refTime) { var referenceTime = refTime ?? DateObject.Now; DateTimeParseResult pr = null; // push, save teh MOD string bool hasBefore = false, hasAfter = false; var modStr = string.Empty; if (BeforeRegex.IsMatch(er.Text)) { hasBefore = true; } else if (AfterRegex.IsMatch(er.Text)) { hasAfter = true; } if (er.Type.Equals(Constants.SYS_DATETIME_DATE)) { pr = this.config.DateParser.Parse(er, referenceTime); if (pr.Value == null) { //pr = this.config.HolidayParser.Parse(er, referenceTime); } } else if (er.Type.Equals(Constants.SYS_DATETIME_TIME)) { pr = this.config.TimeParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DATETIME)) { pr = this.config.DateTimeParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DATEPERIOD)) { pr = this.config.DatePeriodParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_TIMEPERIOD)) { pr = this.config.TimePeriodParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DATETIMEPERIOD)) { pr = this.config.DateTimePeriodParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DURATION)) { pr = this.config.DurationParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_SET)) { pr = this.config.SetParser.Parse(er, referenceTime); } else { return(null); } // pop, restore the MOD string if (hasBefore) { var val = (DTParseResult)pr.Value; if (val != null) { val.mod = TimeTypeConstants.beforeMod; } pr.Value = val; } if (hasAfter) { var val = (DTParseResult)pr.Value; if (val != null) { val.mod = TimeTypeConstants.afterMod; } pr.Value = val; } pr.Value = DateTimeResolution(pr, hasBefore, hasAfter); //change the type at last for the after or before mode pr.Type = string.Format("{0}.{1}", ParserTypeName, DetermineDateTimeType(er.Type, hasBefore, hasAfter)); return(pr); }
public DateTimeParseResult Parse(ExtractResult er, DateObject refDate) { var referenceTime = refDate; object value = null; if (er.Type.Equals(ParserName, StringComparison.Ordinal)) { var innerResult = MergeDateAndTimePeriod(er.Text, referenceTime); if (!innerResult.Success) { innerResult = MergeTwoTimePoints(er.Text, referenceTime); } if (!innerResult.Success) { innerResult = ParseSpecificNight(er.Text, referenceTime); } if (!innerResult.Success) { innerResult = ParseNumberWithUnit(er.Text, referenceTime); } if (innerResult.Success) { innerResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.START_DATETIME, DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)innerResult.FutureValue).Item1) }, { TimeTypeConstants.END_DATETIME, DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)innerResult.FutureValue).Item2) }, }; innerResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.START_DATETIME, DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)innerResult.PastValue).Item1) }, { TimeTypeConstants.END_DATETIME, DateTimeFormatUtil.FormatDateTime(((Tuple <DateObject, DateObject>)innerResult.PastValue).Item2) }, }; 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); }
public new ParseResult Parse(ExtractResult er, DateObject refTime) { var referenceTime = refTime; DateTimeParseResult pr = null; // push, save teh MOD string bool hasBefore = false, hasAfter = false, hasSince = false; var modStr = string.Empty; if (BeforeRegex.IsMatch(er.Text)) { hasBefore = true; } else if (AfterRegex.IsMatch(er.Text)) { hasAfter = true; } else if (SinceRegex.IsMatch(er.Text)) { hasSince = true; } if (er.Type.Equals(Constants.SYS_DATETIME_DATE)) { pr = this.Config.DateParser.Parse(er, referenceTime); if (pr.Value == null) { //pr = this.config.HolidayParser.Parse(er, referenceTime); } } else if (er.Type.Equals(Constants.SYS_DATETIME_TIME)) { pr = this.Config.TimeParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DATETIME)) { pr = this.Config.DateTimeParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DATEPERIOD)) { pr = this.Config.DatePeriodParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_TIMEPERIOD)) { pr = this.Config.TimePeriodParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DATETIMEPERIOD)) { pr = this.Config.DateTimePeriodParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_DURATION)) { pr = this.Config.DurationParser.Parse(er, referenceTime); } else if (er.Type.Equals(Constants.SYS_DATETIME_SET)) { pr = this.Config.SetParser.Parse(er, referenceTime); } else { return(null); } // pop, restore the MOD string if (hasBefore) { var val = (DateTimeResolutionResult)pr.Value; if (val != null) { val.Mod = Constants.BEFORE_MOD; } pr.Value = val; } if (hasAfter) { var val = (DateTimeResolutionResult)pr.Value; if (val != null) { val.Mod = Constants.AFTER_MOD; } pr.Value = val; } if (hasSince) { var val = (DateTimeResolutionResult)pr.Value; if (val != null) { val.Mod = Constants.SINCE_MOD; } pr.Value = val; } pr.Value = DateTimeResolution(pr); var hasModifier = hasBefore || hasAfter || hasSince; //change the type at last for the after or before mode pr.Type = $"{ParserTypeName}.{DetermineDateTimeType(er.Type, hasModifier)}"; return(pr); }
public DateTimeParseResult Parse(ExtractResult er, DateObject refDate) { var referenceTime = refDate; var extra = er.Data as DateTimeExtra <PeriodType>; if (extra == null) { var result = new JapaneseTimeExtractorConfiguration().Extract(er.Text, refDate); extra = result[0]?.Data as DateTimeExtra <PeriodType>; } if (extra != null) { // Handle special case like '上午', '下午' var parseResult = ParseJapaneseTimeOfDay(er.Text, referenceTime); if (!parseResult.Success) { parseResult = TimePeriodFunctions.Handle(this.config.TimeParser, extra, referenceTime, timeFunc); } if (parseResult.Success) { parseResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.START_TIME, DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)parseResult.FutureValue).Item1) }, { TimeTypeConstants.END_TIME, DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)parseResult.FutureValue).Item2) }, }; parseResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.START_TIME, DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)parseResult.PastValue).Item1) }, { TimeTypeConstants.END_TIME, DateTimeFormatUtil.FormatTime(((Tuple <DateObject, DateObject>)parseResult.PastValue).Item2) }, }; } var ret = new DateTimeParseResult { Start = er.Start, Text = er.Text, Type = er.Type, Length = er.Length, Value = parseResult, ResolutionStr = string.Empty, TimexStr = parseResult.Timex, }; return(ret); } return(null); }
public DateTimeParseResult Parse(ExtractResult er, DateObject refDate) { var referenceTime = refDate; // handle cases like "三年半" var hasHalfSuffix = false; if (er.Text.EndsWith("半")) { er.Length -= 1; er.Text = er.Text.Substring(0, er.Text.Length - 1); hasHalfSuffix = true; } var parseResult = InternalParser.Parse(er); var unitResult = parseResult.Value as UnitValue; if (unitResult == null) { return(null); } var dtParseResult = new DateTimeResolutionResult(); var unitStr = unitResult.Unit; var numStr = unitResult.Number; if (hasHalfSuffix) { numStr = (double.Parse(numStr) + 0.5).ToString(CultureInfo.InvariantCulture); } dtParseResult.Timex = "P" + (BaseDurationParser.IsLessThanDay(unitStr) ? "T" : "") + numStr + unitStr[0]; dtParseResult.FutureValue = dtParseResult.PastValue = double.Parse(numStr) * UnitValueMap[unitStr]; dtParseResult.Success = true; if (dtParseResult.Success) { dtParseResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.DURATION, dtParseResult.FutureValue.ToString() } }; dtParseResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.DURATION, dtParseResult.PastValue.ToString() } }; } var ret = new DateTimeParseResult { Text = er.Text, Start = er.Start, Length = er.Length, Type = er.Type, Data = er.Data, Value = dtParseResult, TimexStr = dtParseResult.Timex, ResolutionStr = "" }; return(ret); }
private DateTimeResolutionResult MergeTwoTimePoints(string text, DateObject referenceTime) { var ret = new DateTimeResolutionResult(); DateTimeParseResult pr1 = null, pr2 = null; bool bothHasDate = false, beginHasDate = false, endHasDate = false; var er1 = _singleTimeExtractor.Extract(text); var er2 = _timeWithDateExtractor.Extract(text); if (er2.Count == 2) { pr1 = this.config.DateTimeParser.Parse(er2[0], referenceTime); pr2 = this.config.DateTimeParser.Parse(er2[1], referenceTime); bothHasDate = true; } else if (er2.Count == 1 && er1.Count == 2) { if (!er2[0].IsOverlap(er1[0])) { pr1 = this.config.TimeParser.Parse(er1[0], referenceTime); pr2 = this.config.DateTimeParser.Parse(er2[0], referenceTime); endHasDate = true; } else { pr1 = this.config.DateTimeParser.Parse(er2[0], referenceTime); pr2 = this.config.TimeParser.Parse(er1[1], referenceTime); beginHasDate = true; } } else if (er2.Count == 1 && er1.Count == 1) { if (er1[0].Start < er2[0].Start) { pr1 = this.config.TimeParser.Parse(er1[0], referenceTime); pr2 = this.config.DateTimeParser.Parse(er2[0], referenceTime); endHasDate = true; } else { pr1 = this.config.DateTimeParser.Parse(er2[0], referenceTime); pr2 = this.config.TimeParser.Parse(er1[0], referenceTime); beginHasDate = true; } } else if (er1.Count == 2) { // if both ends are Time. then this is a TimePeriod, not a DateTimePeriod return(ret); } else { return(ret); } if (pr1.Value == null || pr2.Value == null) { return(ret); } DateObject futureBegin = (DateObject)((DateTimeResolutionResult)pr1.Value).FutureValue, futureEnd = (DateObject)((DateTimeResolutionResult)pr2.Value).FutureValue; DateObject pastBegin = (DateObject)((DateTimeResolutionResult)pr1.Value).PastValue, pastEnd = (DateObject)((DateTimeResolutionResult)pr2.Value).PastValue; if (futureBegin > futureEnd) { futureBegin = pastBegin; } if (pastEnd < pastBegin) { pastEnd = futureEnd; } if (bothHasDate) { ret.Timex = $"({pr1.TimexStr},{pr2.TimexStr},PT{Convert.ToInt32((futureEnd - futureBegin).TotalHours)}H)"; // do nothing } else if (beginHasDate) { // TODO: Handle "明天下午两点到五点" futureEnd = new DateObject(futureBegin.Year, futureBegin.Month, futureBegin.Day, futureEnd.Hour, futureEnd.Minute, futureEnd.Second); pastEnd = new DateObject(pastBegin.Year, pastBegin.Month, pastBegin.Day, pastEnd.Hour, pastEnd.Minute, pastEnd.Second); var dateStr = pr1.TimexStr.Split('T')[0]; ret.Timex = $"({pr1.TimexStr},{dateStr + pr2.TimexStr},PT{Convert.ToInt32((futureEnd - futureBegin).TotalHours)}H)"; } else if (endHasDate) { // TODO: Handle "明天下午两点到五点" futureBegin = new DateObject(futureEnd.Year, futureEnd.Month, futureEnd.Day, futureBegin.Hour, futureBegin.Minute, futureBegin.Second); pastBegin = new DateObject(pastEnd.Year, pastEnd.Month, pastEnd.Day, pastBegin.Hour, pastBegin.Minute, pastBegin.Second); var dateStr = pr2.TimexStr.Split('T')[0]; ret.Timex = $"({dateStr + pr1.TimexStr},{pr2.TimexStr},PT{Convert.ToInt32((futureEnd - futureBegin).TotalHours)}H)"; } ret.FutureValue = new Tuple <DateObject, DateObject>(futureBegin, futureEnd); ret.PastValue = new Tuple <DateObject, DateObject>(pastBegin, pastEnd); ret.Success = true; return(ret); }
public DateTimeParseResult Parse(ExtractResult er, DateObject refDate) { var referenceDate = refDate; object value = null; var luisStr = string.Empty; var valueStr = string.Empty; if (er.Type.Equals(ParserName)) { var innerResult = ParseSimpleCases(er.Text, referenceDate); if (!innerResult.Success) { innerResult = ParseOneWordPeriod(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = MergeTwoTimePoints(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseNumberWithUnit(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseYearAndMonth(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseYearToYear(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseYear(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseWeekOfMonth(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseSeason(er.Text, referenceDate); } if (!innerResult.Success) { innerResult = ParseQuarter(er.Text, referenceDate); } if (innerResult.Success) { if (innerResult.FutureValue != null && innerResult.PastValue != null) { innerResult.FutureResolution = new Dictionary <string, string> { { TimeTypeConstants.START_DATE, Util.FormatDate(((Tuple <DateObject, DateObject>)innerResult.FutureValue).Item1) }, { TimeTypeConstants.END_DATE, Util.FormatDate(((Tuple <DateObject, DateObject>)innerResult.FutureValue).Item2) } }; innerResult.PastResolution = new Dictionary <string, string> { { TimeTypeConstants.START_DATE, Util.FormatDate(((Tuple <DateObject, DateObject>)innerResult.PastValue).Item1) }, { TimeTypeConstants.END_DATE, Util.FormatDate(((Tuple <DateObject, DateObject>)innerResult.PastValue).Item2) } }; } else { innerResult.PastResolution = innerResult.FutureResolution = new Dictionary <string, string>(); } 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 ? "" : ((DTParseResult)value).Timex, ResolutionStr = "" }; return(ret); }