Пример #1
0
        public DateTimeParseResult Parse(ExtractResult er, DateObject refDate)
        {
            var    referenceDate = refDate;
            object value         = null;

            if (er.Type.Equals(ParserName))
            {
                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 ? "" : ((DateTimeResolutionResult)value).Timex,
                ResolutionStr = ""
            };

            return(ret);
        }
Пример #2
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 = ParserDurationWithBeforeAndAfter(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);
        }
Пример #3
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 (ChineseDateTimePeriodExtractorConfiguration.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true))
            {
                var swift = 0;
                switch (trimmedText)
                {
                case "今晚":
                    swift     = 0;
                    timeStr   = "TEV";
                    beginHour = 16;
                    endHour   = 20;
                    break;

                case "今早":
                case "今晨":
                    swift     = 0;
                    timeStr   = "TMO";
                    beginHour = 8;
                    endHour   = Constants.HalfDayHourCount;
                    break;

                case "明晚":
                    swift     = 1;
                    timeStr   = "TEV";
                    beginHour = 16;
                    endHour   = 20;
                    break;

                case "明早":
                case "明晨":
                    swift     = 1;
                    timeStr   = "TMO";
                    beginHour = 8;
                    endHour   = Constants.HalfDayHourCount;
                    break;

                case "昨晚":
                    swift     = -1;
                    timeStr   = "TEV";
                    beginHour = 16;
                    endHour   = 20;
                    break;

                default:
                    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 (MORegex.IsMatch(trimmedText))
            {
                timeStr   = "TMO";
                beginHour = 8;
                endHour   = Constants.HalfDayHourCount;
            }
            else if (MIRegex.IsMatch(trimmedText))
            {
                timeStr   = "TMI";
                beginHour = 11;
                endHour   = 13;
            }
            else if (AFRegex.IsMatch(trimmedText))
            {
                timeStr   = "TAF";
                beginHour = Constants.HalfDayHourCount;
                endHour   = 16;
            }
            else if (EVRegex.IsMatch(trimmedText))
            {
                timeStr   = "TEV";
                beginHour = 16;
                endHour   = 20;
            }
            else if (NIRegex.IsMatch(trimmedText))
            {
                timeStr   = "TNI";
                beginHour = 20;
                endHour   = 23;
                endMin    = 59;
            }
            else
            {
                return(ret);
            }

            if (ChineseDateTimePeriodExtractorConfiguration.SpecificTimeOfDayRegex.IsExactMatch(trimmedText, trim: true))
            {
                var swift = 0;
                if (ChineseDateTimePeriodExtractorConfiguration.NextRegex.IsMatch(trimmedText))
                {
                    swift = 1;
                }
                else if (ChineseDateTimePeriodExtractorConfiguration.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 = ChineseDateTimePeriodExtractorConfiguration.TimeOfDayRegex.Match(trimmedText);

            if (match.Success)
            {
                var beforeStr = trimmedText.Substring(0, match.Index).Trim();
                var ers       = SingleDateExtractor.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);
        }
Пример #4
0
        protected override DateTimeResolutionResult ParseSpecificTimeOfDay(string text, DateObject referenceTime)
        {
            var ret         = new DateTimeResolutionResult();
            var trimmedText = text.Trim().ToLowerInvariant();

            // handle morning, afternoon..
            if (!this.Config.GetMatchedTimeRange(trimmedText, out string timeStr, out int beginHour, out int endHour, out int endMin))
            {
                return(ret);
            }

            var exactMatch = this.Config.SpecificTimeOfDayRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                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);
            }

            var startIndex = trimmedText.IndexOf(DateTimeDefinitions.Tomorrow, StringComparison.Ordinal) == 0 ? DateTimeDefinitions.Tomorrow.Length : 0;

            // handle Date followed by morning, afternoon
            // Add handling code to handle morning, afternoon followed by Date
            // Add handling code to handle early/late morning, afternoon
            var match = this.Config.TimeOfDayRegex.Match(trimmedText.Substring(startIndex));

            if (match.Success)
            {
                var beforeStr = trimmedText.Substring(0, match.Index + startIndex).Trim();
                var ers       = this.Config.DateExtractor.Extract(beforeStr, referenceTime);

                if (ers.Count == 0)
                {
                    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);
        }
Пример #5
0
        protected override DateTimeResolutionResult ParseSpecificTimeOfDay(string text, DateObject referenceTime)
        {
            var ret         = new DateTimeResolutionResult();
            var trimmedText = text.Trim();

            // handle morning, afternoon..
            if (!this.Config.GetMatchedTimeRange(trimmedText, out string timeStr, out int beginHour, out int endHour, out int endMin))
            {
                return(ret);
            }

            var exactMatch = this.Config.SpecificTimeOfDayRegex.MatchExact(trimmedText, trim: true);

            if (!exactMatch.Success)
            {
                exactMatch = this.Config.PeriodTimeOfDayWithDateRegex.MatchExact(trimmedText, trim: true);
            }

            if (exactMatch.Success)
            {
                // Extract early/late prefix from text if any
                bool hasEarly = false;
                if (!string.IsNullOrEmpty(exactMatch.Groups["early"].Value))
                {
                    hasEarly    = true;
                    ret.Comment = Constants.Comment_Early;
                    ret.Mod     = Constants.EARLY_MOD;
                    endHour     = beginHour + 2;

                    // Handling special case: night ends with 23:59 due to C# issues.
                    if (endMin == 59)
                    {
                        endMin = 0;
                    }
                }

                if (!hasEarly && !string.IsNullOrEmpty(exactMatch.Groups["late"].Value))
                {
                    ret.Comment = Constants.Comment_Late;
                    ret.Mod     = Constants.LATE_MOD;
                    beginHour   = beginHour + 2;
                }

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

            var startIndex = trimmedText.IndexOf(DateTimeDefinitions.Tomorrow, StringComparison.Ordinal) == 0 ? DateTimeDefinitions.Tomorrow.Length : 0;

            // handle Date preceded/followed by morning, afternoon
            // @TODO Add handling code to handle early/late morning, afternoon
            var match = this.Config.TimeOfDayRegex.Match(trimmedText.Substring(startIndex));

            if (match.Success)
            {
                var subStr = match.Index > 0 ? trimmedText.Substring(0, match.Index + startIndex).Trim() : trimmedText.Substring(match.Index + match.Length).Trim();
                var ers    = this.Config.DateExtractor.Extract(subStr, referenceTime);

                if (ers.Count == 0)
                {
                    return(ret);
                }

                // Check if Date and TimeOfDay are contiguous
                var middleStr = match.Index > 0 ? subStr.Substring((int)ers[0].Start + (int)ers[0].Length).Trim() : subStr.Substring(0, (int)ers[0].Start).Trim();
                if (!(string.IsNullOrWhiteSpace(middleStr) || ConnectorRegex.IsMatch(middleStr)))
                {
                    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);
        }
Пример #6
0
        private DateTimeResolutionResult ParseTimeOfToday(string text, DateObject referenceTime)
        {
            var ret = new DateTimeResolutionResult();
            var ers = SingleTimeExtractor.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 == null)
            {
                return(ret);
            }

            var time = (DateObject)((DateTimeResolutionResult)pr.Value).FutureValue;

            var hour = time.Hour;
            var min  = time.Minute;
            var sec  = time.Second;

            var match = ChineseDateTimeExtractorConfiguration.TimeOfTodayRegex.Match(text);

            if (match.Success)
            {
                var matchStr = match.Value;

                var swift = 0;

                // @TODO move hardcoded values to resources file

                switch (matchStr)
                {
                case "今晚":
                    if (hour < Constants.HalfDayHourCount)
                    {
                        hour += Constants.HalfDayHourCount;
                    }

                    break;

                case "今早":
                case "今晨":
                    if (hour >= Constants.HalfDayHourCount)
                    {
                        hour -= Constants.HalfDayHourCount;
                    }

                    break;

                case "明晚":
                    swift = 1;
                    if (hour < Constants.HalfDayHourCount)
                    {
                        hour += Constants.HalfDayHourCount;
                    }

                    break;

                case "明早":
                case "明晨":
                    swift = 1;
                    if (hour >= Constants.HalfDayHourCount)
                    {
                        hour -= Constants.HalfDayHourCount;
                    }

                    break;

                case "昨晚":
                    swift = -1;
                    if (hour < Constants.HalfDayHourCount)
                    {
                        hour += Constants.HalfDayHourCount;
                    }

                    break;

                default:
                    break;
                }

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