// match several other cases
        // including 'today', 'the day after tomorrow', 'on 13'
        private DateTimeResolutionResult ParseImplicitDate(string text, DateObject referenceDate)
        {
            var trimmedText = text.Trim();

            var ret = new DateTimeResolutionResult();

            // handle "on 12"
            var match = this.config.OnRegex.Match(this.config.DateTokenPrefix + trimmedText);

            if (match.Success && match.Index == 3 && match.Length == trimmedText.Length)
            {
                int month = referenceDate.Month, year = referenceDate.Year;
                var dayStr = match.Groups["day"].Value.ToLower();
                var day    = this.config.DayOfMonth[dayStr];

                ret.Timex = DateTimeFormatUtil.LuisDate(-1, -1, day);

                DateObject futureDate, pastDate;
                var        tryStr = DateTimeFormatUtil.LuisDate(year, month, day);
                if (DateObject.TryParse(tryStr, out DateObject _))
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
                    pastDate   = DateObject.MinValue.SafeCreateFromValue(year, month, day);

                    if (futureDate < referenceDate)
                    {
                        futureDate = futureDate.AddMonths(+1);
                    }

                    if (pastDate >= referenceDate)
                    {
                        pastDate = pastDate.AddMonths(-1);
                    }
                }
                else
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month + 1, day);
                    pastDate   = DateObject.MinValue.SafeCreateFromValue(year, month - 1, day);
                }

                ret.FutureValue = futureDate;
                ret.PastValue   = pastDate;
                ret.Success     = true;

                return(ret);
            }

            // handle "today", "the day before yesterday"
            match = this.config.SpecialDayRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var swift = GetSwiftDay(match.Value);

                var value = referenceDate.AddDays(swift);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // handle "two days from tomorrow"
            match = this.config.SpecialDayWithNumRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var swift     = GetSwiftDay(match.Groups["day"].Value);
                var numErs    = this.config.IntegerExtractor.Extract(trimmedText);
                var numOfDays = Convert.ToInt32((double)(this.config.NumberParser.Parse(numErs[0]).Value ?? 0));

                var value = referenceDate.AddDays(numOfDays + swift);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // handle "two sundays from now"
            match = this.config.RelativeWeekDayRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var numErs     = this.config.IntegerExtractor.Extract(trimmedText);
                var num        = Convert.ToInt32((double)(this.config.NumberParser.Parse(numErs[0]).Value ?? 0));
                var weekdayStr = match.Groups["weekday"].Value.ToLower();
                var value      = referenceDate;

                // Check whether the determined day of this week has passed.
                if (value.DayOfWeek > (DayOfWeek)this.config.DayOfWeek[weekdayStr])
                {
                    num--;
                }

                while (num-- > 0)
                {
                    value = value.Next((DayOfWeek)this.config.DayOfWeek[weekdayStr]);
                }

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // handle "next Sunday"
            match = this.config.NextRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var weekdayStr = match.Groups["weekday"].Value.ToLower();
                var value      = referenceDate.Next((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // handle "this Friday"
            match = this.config.ThisRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var weekdayStr = match.Groups["weekday"].Value.ToLower();
                var value      = referenceDate.This((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // handle "last Friday", "last mon"
            match = this.config.LastRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var weekdayStr = match.Groups["weekday"].Value.ToLower();
                var value      = referenceDate.Last((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // handle "Friday"
            match = this.config.WeekDayRegex.Match(trimmedText);
            if (match.Success && match.Index == 0 && match.Length == trimmedText.Length)
            {
                var weekdayStr = match.Groups["weekday"].Value.ToLower();
                var weekDay    = this.config.DayOfWeek[weekdayStr];
                var value      = referenceDate.This((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                if (weekDay == 0)
                {
                    weekDay = 7;
                }

                if (weekDay < (int)referenceDate.DayOfWeek)
                {
                    value = referenceDate.Next((DayOfWeek)weekDay);
                }

                ret.Timex = "XXXX-WXX-" + weekDay;
                var futureDate = value;
                var pastDate   = value;
                if (futureDate < referenceDate)
                {
                    futureDate = futureDate.AddDays(7);
                }

                if (pastDate >= referenceDate)
                {
                    pastDate = pastDate.AddDays(-7);
                }

                ret.FutureValue = futureDate;
                ret.PastValue   = pastDate;
                ret.Success     = true;

                return(ret);
            }

            // handle "for the 27th."
            match = this.config.ForTheRegex.Match(text);
            if (match.Success)
            {
                int day = 0, month = referenceDate.Month, year = referenceDate.Year;
                var dayStr = match.Groups["DayOfMonth"].Value.ToLower();

                // create a extract result which content ordinal string of text
                ExtractResult er = new ExtractResult
                {
                    Text   = dayStr,
                    Start  = match.Groups["DayOfMonth"].Index,
                    Length = match.Groups["DayOfMonth"].Length
                };

                day = Convert.ToInt32((double)(this.config.NumberParser.Parse(er).Value ?? 0));

                ret.Timex = DateTimeFormatUtil.LuisDate(-1, -1, day);

                DateObject futureDate;
                var        tryStr = DateTimeFormatUtil.LuisDate(year, month, day);
                if (DateObject.TryParse(tryStr, out DateObject _))
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
                }
                else
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month + 1, day);
                }

                ret.FutureValue = futureDate;
                ret.PastValue   = ret.FutureValue;
                ret.Success     = true;

                return(ret);
            }

            // handling cases like 'Thursday the 21st', which both 'Thursday' and '21st' refer to a same date
            match = this.config.WeekDayAndDayOfMothRegex.Match(text);
            if (match.Success)
            {
                int month = referenceDate.Month, year = referenceDate.Year;
                // create a extract result which content ordinal string of text
                ExtractResult erTmp = new ExtractResult
                {
                    Text   = match.Groups["DayOfMonth"].Value,
                    Start  = match.Groups["DayOfMonth"].Index,
                    Length = match.Groups["DayOfMonth"].Length
                };

                // parse the day in text into number
                var day = Convert.ToInt32((double)(this.config.NumberParser.Parse(erTmp).Value ?? 0));

                // the validity of the phrase is guaranteed in the Date Extractor
                ret.Timex       = DateTimeFormatUtil.LuisDate(year, month, day);
                ret.FutureValue = new DateObject(year, month, day);;
                ret.PastValue   = new DateObject(year, month, day);;
                ret.Success     = true;

                return(ret);
            }

            return(ret);
        }
Beispiel #2
0
        // Handle cases like "January first", "twenty-two of August"
        // Handle cases like "20th of next month"
        private DateTimeResolutionResult ParseNumberWithMonth(string text, DateObject referenceDate)
        {
            var ret = new DateTimeResolutionResult();

            var  trimmedText = text.Trim().ToLower();
            int  month = 0, day = 0, year = referenceDate.Year;
            bool ambiguous = true;

            var er = this.config.OrdinalExtractor.Extract(trimmedText);

            if (er.Count == 0)
            {
                er = this.config.IntegerExtractor.Extract(trimmedText);
            }

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

            var num = Convert.ToInt32((double)(this.config.NumberParser.Parse(er[0]).Value ?? 0));

            var match = this.config.MonthRegex.Match(trimmedText);

            if (match.Success)
            {
                month = this.config.MonthOfYear[match.Value.Trim()];
                day   = num;

                var suffix    = trimmedText.Substring(er[0].Start + er[0].Length ?? 0);
                var matchYear = this.config.YearSuffix.Match(suffix);
                if (matchYear.Success)
                {
                    year = ((BaseDateExtractor)this.config.DateExtractor).GetYearFromText(matchYear);
                    if (year != Constants.InvalidYear)
                    {
                        ambiguous = false;
                    }
                }
            }

            // Handling relative month
            if (!match.Success)
            {
                match = this.config.RelativeMonthRegex.Match(trimmedText);
                if (match.Success)
                {
                    var monthStr = match.Groups["order"].Value;
                    var swift    = this.config.GetSwiftMonth(monthStr);
                    month     = referenceDate.AddMonths(swift).Month;
                    year      = referenceDate.AddMonths(swift).Year;
                    day       = num;
                    ambiguous = false;
                }
            }

            // Handling cases like 'second Sunday'
            if (!match.Success)
            {
                match = this.config.WeekDayRegex.Match(trimmedText);
                if (match.Success)
                {
                    month = referenceDate.Month;

                    // Resolve the date of wanted week day
                    var wantedWeekDay      = this.config.DayOfWeek[match.Groups["weekday"].Value];
                    var firstDate          = DateObject.MinValue.SafeCreateFromValue(referenceDate.Year, referenceDate.Month, 1);
                    var firstWeekDay       = (int)firstDate.DayOfWeek;
                    var firstWantedWeekDay = firstDate.AddDays(wantedWeekDay > firstWeekDay ? wantedWeekDay - firstWeekDay : wantedWeekDay - firstWeekDay + 7);
                    var answerDay          = firstWantedWeekDay.Day + ((num - 1) * 7);
                    day       = answerDay;
                    ambiguous = false;
                }
            }

            if (!match.Success)
            {
                return(ret);
            }

            // For LUIS format value string
            var futureDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
            var pastDate   = DateObject.MinValue.SafeCreateFromValue(year, month, day);

            if (ambiguous)
            {
                ret.Timex = DateTimeFormatUtil.LuisDate(-1, month, day);
                if (futureDate < referenceDate)
                {
                    futureDate = futureDate.AddYears(+1);
                }

                if (pastDate >= referenceDate)
                {
                    pastDate = pastDate.AddYears(-1);
                }
            }
            else
            {
                ret.Timex = DateTimeFormatUtil.LuisDate(year, month, day);
            }

            ret.FutureValue = futureDate;
            ret.PastValue   = pastDate;
            ret.Success     = true;

            return(ret);
        }
Beispiel #3
0
        // Match several other cases
        // Including 'today', 'the day after tomorrow', 'on 13'
        private DateTimeResolutionResult ParseImplicitDate(string text, DateObject referenceDate)
        {
            var trimmedText = text.Trim();

            var ret = new DateTimeResolutionResult();

            // Handle "on 12"
            var match = this.config.OnRegex.Match(this.config.DateTokenPrefix + trimmedText);

            if (match.Success && match.Index == 3 && match.Length == trimmedText.Length)
            {
                int month = referenceDate.Month, year = referenceDate.Year;
                var dayStr = match.Groups["day"].Value.ToLower();
                var day    = this.config.DayOfMonth[dayStr];

                ret.Timex = DateTimeFormatUtil.LuisDate(-1, -1, day);

                DateObject futureDate, pastDate;
                var        tryStr = DateTimeFormatUtil.LuisDate(year, month, day);
                if (DateObject.TryParse(tryStr, out DateObject _))
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
                    pastDate   = DateObject.MinValue.SafeCreateFromValue(year, month, day);

                    if (futureDate < referenceDate)
                    {
                        futureDate = futureDate.AddMonths(+1);
                    }

                    if (pastDate >= referenceDate)
                    {
                        pastDate = pastDate.AddMonths(-1);
                    }
                }
                else
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month + 1, day);
                    pastDate   = DateObject.MinValue.SafeCreateFromValue(year, month - 1, day);
                }

                ret.FutureValue = futureDate;
                ret.PastValue   = pastDate;
                ret.Success     = true;

                return(ret);
            }

            // Handle "today", "the day before yesterday"
            var exactMatch = this.config.SpecialDayRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                var swift = GetSwiftDay(exactMatch.Value);

                var value = referenceDate.AddDays(swift);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // Handle "two days from tomorrow"
            exactMatch = this.config.SpecialDayWithNumRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                var swift     = GetSwiftDay(exactMatch.Groups["day"].Value);
                var numErs    = this.config.IntegerExtractor.Extract(trimmedText);
                var numOfDays = Convert.ToInt32((double)(this.config.NumberParser.Parse(numErs[0]).Value ?? 0));

                var value = referenceDate.AddDays(numOfDays + swift);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // Handle "two sundays from now"
            exactMatch = this.config.RelativeWeekDayRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                var numErs     = this.config.IntegerExtractor.Extract(trimmedText);
                var num        = Convert.ToInt32((double)(this.config.NumberParser.Parse(numErs[0]).Value ?? 0));
                var weekdayStr = exactMatch.Groups["weekday"].Value.ToLower();
                var value      = referenceDate;

                // Check whether the determined day of this week has passed.
                if (value.DayOfWeek > (DayOfWeek)this.config.DayOfWeek[weekdayStr])
                {
                    num--;
                }

                while (num-- > 0)
                {
                    value = value.Next((DayOfWeek)this.config.DayOfWeek[weekdayStr]);
                }

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // Handle "next Sunday", "upcoming Sunday"
            // We define "upcoming Sunday" as the nearest Sunday to come (not include today)
            // We define "next Sunday" as Sunday of next week
            exactMatch = this.config.NextRegex.MatchExact(trimmedText, trim: true);
            if (exactMatch.Success)
            {
                var weekdayStr = exactMatch.Groups["weekday"].Value.ToLower();
                var value      = referenceDate.Next((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                if (this.config.UpcomingPrefixRegex.MatchBegin(trimmedText, trim: true).Success)
                {
                    value = referenceDate.Upcoming((DayOfWeek)this.config.DayOfWeek[weekdayStr]);
                }

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // Handle "this Friday"
            exactMatch = this.config.ThisRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                var weekdayStr = exactMatch.Groups["weekday"].Value.ToLower();
                var value      = referenceDate.This((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // Handle "last Friday", "last mon"
            // We define "past Sunday" as the nearest Sunday that has already passed (not include today)
            // We define "previous Sunday" as Sunday of previous week
            exactMatch = this.config.LastRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                var weekdayStr = exactMatch.Groups["weekday"].Value.ToLower();
                var value      = referenceDate.Last((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                if (this.config.PastPrefixRegex.MatchBegin(trimmedText, trim: true).Success)
                {
                    value = referenceDate.Past((DayOfWeek)this.config.DayOfWeek[weekdayStr]);
                }

                ret.Timex       = DateTimeFormatUtil.LuisDate(value);
                ret.FutureValue = ret.PastValue = value;
                ret.Success     = true;

                return(ret);
            }

            // Handle "Friday"
            exactMatch = this.config.WeekDayRegex.MatchExact(trimmedText, trim: true);

            if (exactMatch.Success)
            {
                var weekdayStr = exactMatch.Groups["weekday"].Value.ToLower();
                var weekDay    = this.config.DayOfWeek[weekdayStr];
                var value      = referenceDate.This((DayOfWeek)this.config.DayOfWeek[weekdayStr]);

                if (weekDay == 0)
                {
                    weekDay = 7;
                }

                if (weekDay < (int)referenceDate.DayOfWeek)
                {
                    value = referenceDate.Next((DayOfWeek)weekDay);
                }

                ret.Timex = "XXXX-WXX-" + weekDay;
                var futureDate = value;
                var pastDate   = value;
                if (futureDate < referenceDate)
                {
                    futureDate = futureDate.AddDays(7);
                }

                if (pastDate >= referenceDate)
                {
                    pastDate = pastDate.AddDays(-7);
                }

                ret.FutureValue = futureDate;
                ret.PastValue   = pastDate;
                ret.Success     = true;

                return(ret);
            }

            // Handle "for the 27th."
            match = this.config.ForTheRegex.Match(text);

            if (match.Success)
            {
                int day = 0, month = referenceDate.Month, year = referenceDate.Year;
                var dayStr = match.Groups["DayOfMonth"].Value.ToLower();

                // Create a extract result which content ordinal string of text
                ExtractResult er = new ExtractResult
                {
                    Text   = dayStr,
                    Start  = match.Groups["DayOfMonth"].Index,
                    Length = match.Groups["DayOfMonth"].Length,
                };

                day = Convert.ToInt32((double)(this.config.NumberParser.Parse(er).Value ?? 0));

                ret.Timex = DateTimeFormatUtil.LuisDate(-1, -1, day);

                DateObject futureDate;
                var        tryStr = DateTimeFormatUtil.LuisDate(year, month, day);
                if (DateObject.TryParse(tryStr, out DateObject _))
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
                }
                else
                {
                    futureDate = DateObject.MinValue.SafeCreateFromValue(year, month + 1, day);
                }

                ret.FutureValue = futureDate;
                ret.PastValue   = ret.FutureValue;
                ret.Success     = true;

                return(ret);
            }

            // Handling cases like 'Thursday the 21st', which both 'Thursday' and '21st' refer to a same date
            match = this.config.WeekDayAndDayOfMothRegex.Match(text);
            if (match.Success)
            {
                int month = referenceDate.Month, year = referenceDate.Year;

                // create a extract result which content ordinal string of text
                ExtractResult extractResultTmp = new ExtractResult
                {
                    Text   = match.Groups["DayOfMonth"].Value,
                    Start  = match.Groups["DayOfMonth"].Index,
                    Length = match.Groups["DayOfMonth"].Length,
                };

                // parse the day in text into number
                var day = Convert.ToInt32((double)(this.config.NumberParser.Parse(extractResultTmp).Value ?? 0));

                // The validity of the phrase is guaranteed in the Date Extractor
                ret.Timex       = DateTimeFormatUtil.LuisDate(year, month, day);
                ret.FutureValue = new DateObject(year, month, day);
                ret.PastValue   = new DateObject(year, month, day);
                ret.Success     = true;

                return(ret);
            }

            // Handling cases like 'Monday 21', which both 'Monday' and '21' refer to the same date.
            // The year of expected date can be different to the year of referenceDate.
            match = this.config.WeekDayAndDayRegex.Match(text);
            if (match.Success)
            {
                int month = referenceDate.Month, year = referenceDate.Year;

                // Create a extract result which content ordinal string of text
                ExtractResult ertmp = new ExtractResult
                {
                    Text   = match.Groups["day"].Value,
                    Start  = match.Groups["day"].Index,
                    Length = match.Groups["day"].Length,
                };

                // Parse the day in text into number
                var day = Convert.ToInt32((double)(this.config.NumberParser.Parse(ertmp).Value ?? 0));

                // Firstly, find a latest date with the "day" as pivotDate.
                // Secondly, if the pivotDate equals the referenced date, in other word, the day of the referenced date is exactly the "day".
                // In this way, check if the pivotDate is the weekday. If so, then the futureDate and the previousDate are the same date (referenced date).
                // Otherwise, increase the pivotDate month by month to find the latest futureDate and decrease the pivotDate month
                // by month to the latest previousDate.
                // Notice: if the "day" is larger than 28, some months should be ignored in the increase or decrease procedure.
                var pivotDate   = new DateObject(year, month, 1);
                var daysInMonth = DateObject.DaysInMonth(year, month);
                if (daysInMonth >= day)
                {
                    pivotDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
                }
                else
                {
                    // Add 1 month is enough, since 1, 3, 5, 7, 8, 10, 12 months has 31 days
                    pivotDate = pivotDate.AddMonths(1);
                    pivotDate = DateObject.MinValue.SafeCreateFromValue(pivotDate.Year, pivotDate.Month, day);
                }

                var numWeekDayInt       = (int)pivotDate.DayOfWeek;
                var extractedWeekDayStr = match.Groups["weekday"].Value.ToLower();
                var weekDay             = this.config.DayOfWeek[extractedWeekDayStr];
                if (!pivotDate.Equals(DateObject.MinValue))
                {
                    if (day == referenceDate.Day && numWeekDayInt == weekDay)
                    {
                        // The referenceDate is the weekday and with the "day".
                        ret.FutureValue = new DateObject(year, month, day);
                        ret.PastValue   = new DateObject(year, month, day);
                        ret.Timex       = DateTimeFormatUtil.LuisDate(year, month, day);
                    }
                    else
                    {
                        var futureDate = pivotDate;
                        var pastDate   = pivotDate;

                        while ((int)futureDate.DayOfWeek != weekDay || futureDate.Day != day || futureDate < referenceDate)
                        {
                            // Increase the futureDate month by month to find the expected date (the "day" is the weekday) and
                            // make sure the futureDate not less than the referenceDate.
                            futureDate = futureDate.AddMonths(1);
                            var tmp = DateObject.DaysInMonth(futureDate.Year, futureDate.Month);
                            if (tmp >= day)
                            {
                                // For months like January 31, after add 1 month, February 31 won't be returned, so the day should be revised ASAP.
                                futureDate = futureDate.SafeCreateFromValue(futureDate.Year, futureDate.Month, day);
                            }
                        }

                        ret.FutureValue = futureDate;

                        while ((int)pastDate.DayOfWeek != weekDay || pastDate.Day != day || pastDate > referenceDate)
                        {
                            // Decrease the pastDate month by month to find the expected date (the "day" is the weekday) and
                            // make sure the pastDate not larger than the referenceDate.
                            pastDate = pastDate.AddMonths(-1);
                            var tmp = DateObject.DaysInMonth(pastDate.Year, pastDate.Month);
                            if (tmp >= day)
                            {
                                // For months like March 31, after minus 1 month, February 31 won't be returned, so the day should be revised ASAP.
                                pastDate = pastDate.SafeCreateFromValue(pastDate.Year, pastDate.Month, day);
                            }
                        }

                        ret.PastValue = pastDate;

                        if (weekDay == 0)
                        {
                            weekDay = 7;
                        }

                        ret.Timex = "XXXX-WXX-" + weekDay;
                    }
                }

                ret.Success = true;

                return(ret);
            }

            return(ret);
        }
        public static string GenerateDatePeriodTimex(DateObject begin, DateObject end, DatePeriodTimexType timexType, UnspecificDateTimeTerms terms)
        {
            var beginYear  = begin.Year;
            var endYear    = end.Year;
            var beginMonth = begin.Month;
            var endMonth   = end.Month;
            var beginDay   = begin.Day;
            var endDay     = end.Day;

            if ((terms & UnspecificDateTimeTerms.NonspecificYear) != 0)
            {
                beginYear = endYear = -1;
            }

            if ((terms & UnspecificDateTimeTerms.NonspecificMonth) != 0)
            {
                beginMonth = endMonth = -1;
            }

            if ((terms & UnspecificDateTimeTerms.NonspecificDay) != 0)
            {
                beginDay = endDay = -1;
            }

            var unitCount = GetDatePeriodTimexUnitCount(begin, end, timexType);

            var datePeriodTimex = $"P{unitCount}{DatePeriodTimexTypeToTimexSuffix[timexType]}";

            return($"({DateTimeFormatUtil.LuisDate(beginYear, beginMonth, beginDay)},{DateTimeFormatUtil.LuisDate(endYear, endMonth, endDay)},{datePeriodTimex})");
        }
        public static string GenerateYearTimex(int year, string specialYearPrefixes = null)
        {
            var yearTimex = DateTimeFormatUtil.LuisDate(year);

            return(specialYearPrefixes == null ? yearTimex : specialYearPrefixes + yearTimex);
        }
Beispiel #6
0
        // Parse a regex match which includes 'day', 'month' and 'year' (optional) group
        private DateTimeResolutionResult Match2Date(Match match, DateObject referenceDate, string relativeStr)
        {
            var ret = new DateTimeResolutionResult();

            var monthStr = match.Groups["month"].Value.ToLower();
            var dayStr = match.Groups["day"].Value.ToLower();
            var yearStr = match.Groups["year"].Value.ToLower();
            var weekdayStr = match.Groups["weekday"].Value.ToLower();
            int month = 0, day = 0, year = 0;

            if (this.config.MonthOfYear.ContainsKey(monthStr) && this.config.DayOfMonth.ContainsKey(dayStr))
            {
                month = this.config.MonthOfYear[monthStr];
                day   = this.config.DayOfMonth[dayStr];
                if (!string.IsNullOrEmpty(yearStr))
                {
                    year = int.Parse(yearStr);
                    if (year < 100 && year >= Constants.MinTwoDigitYearPastNum)
                    {
                        year += 1900;
                    }
                    else if (year >= 0 && year < Constants.MaxTwoDigitYearFutureNum)
                    {
                        year += 2000;
                    }
                }
            }

            var noYear = false;

            if (year == 0)
            {
                year = referenceDate.Year;
                if (!string.IsNullOrEmpty(relativeStr))
                {
                    var swift = this.config.GetSwiftMonthOrYear(relativeStr);

                    // @TODO Improve handling of next/last in particular cases "next friday 5/12" when the next friday is not 5/12.
                    if (!string.IsNullOrEmpty(weekdayStr))
                    {
                        swift = 0;
                    }

                    year += swift;
                }
                else
                {
                    noYear = true;
                }

                ret.Timex = DateTimeFormatUtil.LuisDate(-1, month, day);
            }
            else
            {
                ret.Timex = DateTimeFormatUtil.LuisDate(year, month, day);
            }

            var futureDate = DateObject.MinValue.SafeCreateFromValue(year, month, day);
            var pastDate   = DateObject.MinValue.SafeCreateFromValue(year, month, day);

            if (noYear && futureDate < referenceDate)
            {
                futureDate = futureDate.AddYears(+1);
            }

            if (noYear && pastDate >= referenceDate)
            {
                pastDate = pastDate.AddYears(-1);
            }

            ret.FutureValue = futureDate;
            ret.PastValue   = pastDate;
            ret.Success     = true;

            return(ret);
        }