// 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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #7
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        // 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);
        }
Пример #12
0
        // 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);
        }
Пример #13
0
        // 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);
        }