private DTParseResult Match2Time(Match match, DateObject referenceTime)
        {
            var ret = new DTParseResult();
            int hour = 0,
                min = 0,
                second = 0,
                day = referenceTime.Day,
                month = referenceTime.Month,
                year = referenceTime.Year;
            bool hasMin = false, hasSec = false, hasAm = false, hasPm = false;

            var engTimeStr = match.Groups["engtime"].Value;

            if (!string.IsNullOrEmpty(engTimeStr))
            {
                // get hour
                var hourStr = match.Groups["hournum"].Value.ToLower();
                hour = this.config.Numbers[hourStr];

                // get minute
                var minStr  = match.Groups["minnum"].Value;
                var tensStr = match.Groups["tens"].Value;
                if (!string.IsNullOrEmpty(minStr))
                {
                    min = this.config.Numbers[minStr];
                    if (!string.IsNullOrEmpty(tensStr))
                    {
                        min += this.config.Numbers[tensStr];
                    }
                    hasMin = true;
                }
            }
            else
            {
                // get hour
                var hourStr = match.Groups["hour"].Value;
                if (string.IsNullOrEmpty(hourStr))
                {
                    hourStr = match.Groups["hournum"].Value.ToLower();
                    if (!this.config.Numbers.TryGetValue(hourStr, out hour))
                    {
                        return(ret);
                    }
                }
                else
                {
                    hour = int.Parse(hourStr);
                }

                // get minute
                var minStr = match.Groups["min"].Value.ToLower();
                if (string.IsNullOrEmpty(minStr))
                {
                    minStr = match.Groups["minnum"].Value;
                    if (!string.IsNullOrEmpty(minStr))
                    {
                        min    = this.config.Numbers[minStr];
                        hasMin = true;
                    }
                    var tensStr = match.Groups["tens"].Value;
                    if (!string.IsNullOrEmpty(tensStr))
                    {
                        min   += this.config.Numbers[tensStr];
                        hasMin = true;
                    }
                }
                else
                {
                    min    = int.Parse(minStr);
                    hasMin = true;
                }

                // get second
                var secStr = match.Groups["sec"].Value.ToLower();
                if (!string.IsNullOrEmpty(secStr))
                {
                    second = int.Parse(secStr);
                    hasSec = true;
                }
            }

            //adjust by desc string
            var descStr = match.Groups["desc"].Value.ToLower();

            if (!string.IsNullOrEmpty(descStr))
            {
                if (descStr.ToLower().StartsWith("a"))
                {
                    if (hour >= 12)
                    {
                        hour -= 12;
                    }
                    hasAm = true;
                }
                else if (descStr.ToLower().StartsWith("p"))
                {
                    if (hour < 12)
                    {
                        hour += 12;
                    }
                    hasPm = true;
                }
            }

            // adjust min by prefix
            var timePrefix = match.Groups["prefix"].Value.ToLower();

            if (!string.IsNullOrEmpty(timePrefix))
            {
                this.config.AdjustByPrefix(timePrefix, ref hour, ref min, ref hasMin);
            }

            // adjust hour by suffix
            var timeSuffix = match.Groups["suffix"].Value.ToLower();

            if (!string.IsNullOrEmpty(timeSuffix))
            {
                this.config.AdjustBySuffix(timeSuffix, ref hour, ref min, ref hasMin, ref hasAm, ref hasPm);
            }

            if (hour == 24)
            {
                hour = 0;
            }

            ret.Timex = "T" + hour.ToString("D2");
            if (hasMin)
            {
                ret.Timex += ":" + min.ToString("D2");
            }
            if (hasSec)
            {
                ret.Timex += ":" + second.ToString("D2");
            }
            if (hour <= 12 && !hasPm && !hasAm)
            {
                ret.comment = "ampm";
            }

            ret.FutureValue = ret.PastValue = new DateObject(year, month, day, hour, min, second);
            ret.Success     = true;
            return(ret);
        }
Exemple #2
0
        private DTParseResult ParseOneWordPeriod(string text, DateObject referenceDate)
        {
            var ret = new DTParseResult();
            int year = referenceDate.Year, month = referenceDate.Month;
            int futureYear = year, pastYear = year;

            var trimedText = text.Trim().ToLower();
            var match      = this.config.OneWordPeriodRegex.Match(trimedText);

            if (match.Success && match.Index == 0 && match.Length == trimedText.Length)
            {
                var monthStr = match.Groups["month"].Value;
                if (this.config.IsYearToDate(trimedText))
                {
                    ret.Timex         = referenceDate.Year.ToString("D4");
                    ret.FutureValue   =
                        ret.PastValue =
                            new Tuple <DateObject, DateObject>(new DateObject(referenceDate.Year, 1, 1), referenceDate);
                    ret.Success = true;
                    return(ret);
                }
                if (this.config.IsMonthToDate(trimedText))
                {
                    ret.Timex         = referenceDate.Year.ToString("D4") + "-" + referenceDate.Month.ToString("D2");
                    ret.FutureValue   =
                        ret.PastValue =
                            new Tuple <DateObject, DateObject>(
                                new DateObject(referenceDate.Year, referenceDate.Month, 1), referenceDate);
                    ret.Success = true;
                    return(ret);
                }
                if (!string.IsNullOrEmpty(monthStr))
                {
                    var swift = this.config.GetSwiftYear(trimedText);

                    month = this.config.MonthOfYear[monthStr.ToLower()];

                    if (swift >= -1)
                    {
                        ret.Timex  = (referenceDate.Year + swift).ToString("D4") + "-" + month.ToString("D2");
                        year       = year + swift;
                        futureYear = pastYear = year;
                    }
                    else
                    {
                        ret.Timex = "XXXX-" + month.ToString("D2");
                        if (month < referenceDate.Month)
                        {
                            futureYear++;
                        }
                        if (month >= referenceDate.Month)
                        {
                            pastYear--;
                        }
                    }
                }
                else
                {
                    var swift = this.config.GetSwiftDay(trimedText);

                    if (this.config.IsWeekOnly(trimedText))
                    {
                        var monday = referenceDate.This(DayOfWeek.Monday).AddDays(7 * swift);
                        ret.Timex = monday.Year.ToString("D4") + "-W" +
                                    _cal.GetWeekOfYear(monday, CalendarWeekRule.FirstDay, DayOfWeek.Monday)
                                    .ToString("D2");
                        ret.FutureValue   =
                            ret.PastValue =
                                new Tuple <DateObject, DateObject>(
                                    referenceDate.This(DayOfWeek.Monday).AddDays(7 * swift),
                                    referenceDate.This(DayOfWeek.Sunday).AddDays(7 * swift).AddDays(1));
                        ret.Success = true;
                        return(ret);
                    }
                    if (this.config.IsWeekend(trimedText))
                    {
                        DateObject beginDate, endDate;
                        beginDate = referenceDate.This(DayOfWeek.Saturday).AddDays(7 * swift);
                        endDate   = referenceDate.This(DayOfWeek.Sunday).AddDays(7 * swift);

                        ret.Timex = beginDate.Year.ToString("D4") + "-W" +
                                    _cal.GetWeekOfYear(beginDate, CalendarWeekRule.FirstDay, DayOfWeek.Monday)
                                    .ToString("D2") + "-WE";
                        ret.FutureValue   =
                            ret.PastValue = new Tuple <DateObject, DateObject>(beginDate, endDate.AddDays(1));
                        ret.Success       = true;
                        return(ret);
                    }
                    if (this.config.IsMonthOnly(trimedText))
                    {
                        month      = referenceDate.AddMonths(swift).Month;
                        year       = referenceDate.AddMonths(swift).Year;
                        ret.Timex  = year.ToString("D4") + "-" + month.ToString("D2");
                        futureYear = pastYear = year;
                    }
                    else if (this.config.IsYearOnly(trimedText))
                    {
                        year              = referenceDate.AddYears(swift).Year;
                        ret.Timex         = year.ToString("D4");
                        ret.FutureValue   =
                            ret.PastValue =
                                new Tuple <DateObject, DateObject>(new DateObject(year, 1, 1),
                                                                   new DateObject(year, 12, 31).AddDays(1));
                        ret.Success = true;
                        return(ret);
                    }
                }
            }
            else
            {
                return(ret);
            }

            // only "month" will come to here
            ret.FutureValue = new Tuple <DateObject, DateObject>(
                new DateObject(futureYear, month, 1),
                new DateObject(futureYear, month, 1).AddMonths(1));
            ret.PastValue = new Tuple <DateObject, DateObject>(
                new DateObject(pastYear, month, 1),
                new DateObject(pastYear, month, 1).AddMonths(1));
            ret.Success = true;
            return(ret);
        }
Exemple #3
0
        private DTParseResult ParseNumberWithUnit(string text, DateObject referenceDate)
        {
            var ret = new DTParseResult();

            var numStr  = string.Empty;
            var unitStr = string.Empty;

            // if there are spaces between nubmer and unit
            var ers = this.config.CardinalExtractor.Extract(text);

            if (ers.Count == 1)
            {
                var pr        = this.config.NumberParser.Parse(ers[0]);
                var srcUnit   = text.Substring(ers[0].Start + ers[0].Length ?? 0).Trim().ToLowerInvariant();
                var beforeStr = text.Substring(0, ers[0].Start ?? 0).Trim().ToLowerInvariant();
                if (this.config.UnitMap.ContainsKey(srcUnit))
                {
                    numStr  = pr.ResolutionStr;
                    unitStr = this.config.UnitMap[srcUnit];
                    var prefixMatch = this.config.PastRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        DateObject beginDate, endDate;
                        switch (unitStr)
                        {
                        case "D":
                            beginDate = referenceDate.AddDays(-(double)pr.Value);
                            endDate   = referenceDate;
                            break;

                        case "W":
                            beginDate = referenceDate.AddDays(-7 * (double)pr.Value);
                            endDate   = referenceDate;
                            break;

                        case "MON":
                            beginDate = referenceDate.AddMonths(-Convert.ToInt32((double)pr.Value));
                            endDate   = referenceDate;
                            break;

                        case "Y":
                            beginDate = referenceDate.AddYears(-Convert.ToInt32((double)pr.Value));
                            endDate   = referenceDate;
                            break;

                        default:
                            return(ret);
                        }

                        ret.Timex       = $"({Util.LuisDate(beginDate)},{Util.LuisDate(endDate)},P{numStr}{unitStr[0]})";
                        ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(beginDate, endDate);
                        ret.Success     = true;
                        return(ret);
                    }
                    prefixMatch = this.config.FutureRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        DateObject beginDate, endDate;
                        switch (unitStr)
                        {
                        case "D":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddDays((double)pr.Value);
                            break;

                        case "W":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddDays(7 * (double)pr.Value);
                            break;

                        case "MON":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddMonths(Convert.ToInt32((double)pr.Value));
                            break;

                        case "Y":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddYears(Convert.ToInt32((double)pr.Value));
                            break;

                        default:
                            return(ret);
                        }

                        ret.Timex =
                            $"({Util.LuisDate(beginDate.AddDays(1))},{Util.LuisDate(endDate.AddDays(1))},P{numStr}{unitStr[0]})";
                        ret.FutureValue   =
                            ret.PastValue = new Tuple <DateObject, DateObject>(beginDate.AddDays(1), endDate.AddDays(1));
                        ret.Success       = true;
                        return(ret);
                    }
                }
            }

            // if there are NO spaces between number and unit
            var match = this.config.NumberCombinedWithUnit.Match(text);

            if (match.Success)
            {
                var srcUnit   = match.Groups["unit"].Value.ToLowerInvariant();
                var beforeStr = text.Substring(0, match.Index).Trim().ToLowerInvariant();
                if (this.config.UnitMap.ContainsKey(srcUnit))
                {
                    unitStr = this.config.UnitMap[srcUnit];
                    numStr  = match.Groups["num"].Value;
                    var prefixMatch = this.config.PastRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        DateObject beginDate, endDate;
                        switch (unitStr)
                        {
                        case "D":
                            beginDate = referenceDate.AddDays(-double.Parse(numStr));
                            endDate   = referenceDate;
                            break;

                        case "W":
                            beginDate = referenceDate.AddDays(-7 * double.Parse(numStr));
                            endDate   = referenceDate;
                            break;

                        case "MON":
                            beginDate = referenceDate.AddMonths(-Convert.ToInt32(double.Parse(numStr)));
                            endDate   = referenceDate;
                            break;

                        case "Y":
                            beginDate = referenceDate.AddYears(-Convert.ToInt32(double.Parse(numStr)));
                            endDate   = referenceDate;
                            break;

                        default:
                            return(ret);
                        }
                        ret.Timex       = $"({Util.LuisDate(beginDate)},{Util.LuisDate(endDate)},P{numStr}{unitStr[0]})";
                        ret.FutureValue = ret.PastValue = new Tuple <DateObject, DateObject>(beginDate, endDate);
                        ret.Success     = true;
                        return(ret);
                    }
                    prefixMatch = this.config.FutureRegex.Match(beforeStr);
                    if (prefixMatch.Success && prefixMatch.Length == beforeStr.Length)
                    {
                        DateObject beginDate, endDate;
                        switch (unitStr)
                        {
                        case "D":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddDays(double.Parse(numStr));
                            break;

                        case "W":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddDays(7 * double.Parse(numStr));
                            break;

                        case "MON":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddMonths(Convert.ToInt32(double.Parse(numStr)));
                            break;

                        case "Y":
                            beginDate = referenceDate;
                            endDate   = referenceDate.AddYears(Convert.ToInt32(double.Parse(numStr)));
                            break;

                        default:
                            return(ret);
                        }
                        ret.Timex =
                            $"({Util.LuisDate(beginDate.AddDays(1))},{Util.LuisDate(endDate.AddDays(1))},P{numStr}{unitStr[0]})";
                        ret.FutureValue   =
                            ret.PastValue = new Tuple <DateObject, DateObject>(beginDate.AddDays(1), endDate.AddDays(1));
                        ret.Success       = true;
                        return(ret);
                    }
                }
            }

            return(ret);
        }
Exemple #4
0
        private DTParseResult ParseSimpleCases(string text, DateObject referenceDate)
        {
            var ret = new DTParseResult();
            int year = referenceDate.Year, month = referenceDate.Month;
            int beginDay = referenceDate.Day, endDay = referenceDate.Day;
            var noYear = false;

            var    trimedText = text.Trim();
            var    match = this.config.MonthFrontBetweenRegex.Match(trimedText);
            string beginLuisStr = string.Empty, endLuisStr = string.Empty;

            if (!match.Success)
            {
                match = this.config.BetweenRegex.Match(trimedText);
            }
            if (!match.Success)
            {
                match = this.config.MonthFrontSimpleCasesRegex.Match(trimedText);
            }
            if (!match.Success)
            {
                match = this.config.SimpleCasesRegex.Match(trimedText);
            }
            if (match.Success && match.Index == 0 && match.Length == trimedText.Length)
            {
                var days = match.Groups["day"];
                beginDay = this.config.DayOfMonth[days.Captures[0].Value.ToLower()];
                endDay   = this.config.DayOfMonth[days.Captures[1].Value.ToLower()];

                var monthStr = match.Groups["month"].Value;
                if (!string.IsNullOrEmpty(monthStr))
                {
                    month  = this.config.MonthOfYear[monthStr.ToLower()];
                    noYear = true;
                }
                else
                {
                    monthStr = match.Groups["relmonth"].Value.Trim().ToLower();
                    var swiftMonth = this.config.GetSwiftMonth(monthStr);
                    switch (swiftMonth)
                    {
                    case 1:
                        if (month != 12)
                        {
                            month += 1;
                        }
                        else
                        {
                            month = 1;
                            year += 1;
                        }
                        break;

                    case -1:
                        if (month != 1)
                        {
                            month -= 1;
                        }
                        else
                        {
                            month = 12;
                            year -= 1;
                        }
                        break;

                    default:
                        break;
                    }
                }
                if (this.config.IsFuture(monthStr))
                {
                    beginLuisStr = Util.LuisDate(year, month, beginDay);
                    endLuisStr   = Util.LuisDate(year, month, endDay);
                }
                else
                {
                    beginLuisStr = Util.LuisDate(-1, month, beginDay);
                    endLuisStr   = Util.LuisDate(-1, month, endDay);
                }
            }
            else
            {
                return(ret);
            }

            // parse year
            var yearStr = match.Groups["year"].Value;

            if (!string.IsNullOrEmpty(yearStr))
            {
                year   = int.Parse(yearStr);
                noYear = false;
            }

            int futureYear = year, pastYear = year;
            var startDate = new DateObject(year, month, beginDay);

            if (noYear && startDate < referenceDate)
            {
                futureYear++;
            }
            if (noYear && startDate >= referenceDate)
            {
                pastYear--;
            }

            ret.Timex       = $"({beginLuisStr},{endLuisStr},P{endDay - beginDay}D)";
            ret.FutureValue = new Tuple <DateObject, DateObject>(
                new DateObject(futureYear, month, beginDay),
                new DateObject(futureYear, month, endDay));
            ret.PastValue = new Tuple <DateObject, DateObject>(
                new DateObject(pastYear, month, beginDay),
                new DateObject(pastYear, month, endDay));
            ret.Success = true;

            return(ret);
        }
        // merge a Date entity and a Time entity
        private DTParseResult MergeDateAndTime(string text, DateObject referenceTime)
        {
            var ret = new DTParseResult();

            var er1 = this.config.DateExtractor.Extract(text);

            if (er1.Count == 0)
            {
                er1 = this.config.DateExtractor.Extract(this.config.TokenBeforeDate + text);
                if (er1.Count == 1)
                {
                    er1[0].Start -= this.config.TokenBeforeDate.Length;
                }
                else
                {
                    return(ret);
                }
            }
            else
            {
                // this is to understand if there is an ambiguous token in the text. For some languages (e.g. spanish)
                // the same word could mean different things (e.g a time in the day or an specific day).
                if (this.config.HaveAmbiguousToken(text, er1[0].Text))
                {
                    return(ret);
                }
            }

            var er2 = this.config.TimeExtractor.Extract(text);

            if (er2.Count == 0)
            {
                // here we filter out "morning, afternoon, night..." time entities
                er2 = this.config.TimeExtractor.Extract(this.config.TokenBeforeTime + text);
                if (er2.Count == 1)
                {
                    er2[0].Start -= this.config.TokenBeforeTime.Length;
                }
                else
                {
                    return(ret);
                }
            }

            // handle case "Oct. 5 in the afternoon at 7:00"
            // in this case "5 in the afternoon" will be extract as a Time entity
            var correctTimeIdx = 0;

            while (correctTimeIdx < er2.Count && er2[correctTimeIdx].IsOverlap(er1[0]))
            {
                correctTimeIdx++;
            }
            if (correctTimeIdx >= er2.Count)
            {
                return(ret);
            }

            var pr1 = this.config.DateParser.Parse(er1[0], referenceTime.Date);
            var pr2 = this.config.TimeParser.Parse(er2[correctTimeIdx], referenceTime);

            if (pr1.Value == null || pr2.Value == null)
            {
                return(ret);
            }

            var futureDate = (DateObject)((DTParseResult)pr1.Value).FutureValue;
            var pastDate   = (DateObject)((DTParseResult)pr1.Value).PastValue;
            var time       = (DateObject)((DTParseResult)pr2.Value).FutureValue;

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

            // handle morning, afternoon
            if (this.config.PMTimeRegex.IsMatch(text) && hour < 12)
            {
                hour += 12;
            }
            else if (this.config.AMTimeRegex.IsMatch(text) && hour >= 12)
            {
                hour -= 12;
            }

            var timeStr = pr2.TimexStr;

            if (timeStr.EndsWith("ampm"))
            {
                timeStr = timeStr.Substring(0, timeStr.Length - 4);
            }
            timeStr   = "T" + hour.ToString("D2") + timeStr.Substring(3);
            ret.Timex = pr1.TimexStr + timeStr;

            var val = (DTParseResult)pr2.Value;

            if (hour <= 12 && !this.config.PMTimeRegex.IsMatch(text) && !this.config.AMTimeRegex.IsMatch(text) &&
                !string.IsNullOrEmpty(val.comment))
            {
                //ret.Timex += "ampm";
                ret.comment = "ampm";
            }
            ret.FutureValue = new DateObject(futureDate.Year, futureDate.Month, futureDate.Day, hour, min, sec);
            ret.PastValue   = new DateObject(pastDate.Year, pastDate.Month, pastDate.Day, hour, min, sec);
            ret.Success     = true;

            return(ret);
        }
        private DTParseResult ParseTimeOfToday(string text, DateObject referenceTime)
        {
            var ret        = new DTParseResult();
            var trimedText = text.ToLowerInvariant().Trim();

            int    hour = 0, min = 0, sec = 0;
            string timeStr = string.Empty;

            var wholeMatch = this.config.SimpleTimeOfTodayAfterRegex.Match(trimedText);

            if (!(wholeMatch.Success && wholeMatch.Length == trimedText.Length))
            {
                wholeMatch = this.config.SimpleTimeOfTodayBeforeRegex.Match(trimedText);
            }
            if (wholeMatch.Success && wholeMatch.Length == trimedText.Length)
            {
                var hourStr = wholeMatch.Groups["hour"].Value;
                if (string.IsNullOrEmpty(hourStr))
                {
                    hourStr = wholeMatch.Groups["hournum"].Value.ToLower();
                    hour    = this.config.Numbers[hourStr];
                }
                else
                {
                    hour = int.Parse(hourStr);
                }
                timeStr = "T" + hour.ToString("D2");
            }
            else
            {
                var ers = this.config.TimeExtractor.Extract(trimedText);
                if (ers.Count != 1)
                {
                    ers = this.config.TimeExtractor.Extract(this.config.TokenBeforeTime + trimedText);
                    if (ers.Count == 1)
                    {
                        ers[0].Start -= this.config.TokenBeforeTime.Length;
                    }
                    else
                    {
                        return(ret);
                    }
                }

                var pr = this.config.TimeParser.Parse(ers[0], referenceTime);
                if (pr.Value == null)
                {
                    return(ret);
                }

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

                hour    = time.Hour;
                min     = time.Minute;
                sec     = time.Second;
                timeStr = pr.TimexStr;
            }


            var match = this.config.SpecificNightRegex.Match(trimedText);

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

                // 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, luisStr cannot end up with "ampm", because we always have a "morning" or "night"
                if (timeStr.EndsWith("ampm"))
                {
                    timeStr = timeStr.Substring(0, timeStr.Length - 4);
                }
                timeStr = "T" + hour.ToString("D2") + timeStr.Substring(3);

                ret.Timex       = Util.FormatDate(date) + timeStr;
                ret.FutureValue = ret.PastValue = new DateObject(date.Year, date.Month, date.Day, hour, min, sec);
                ret.Success     = true;
                return(ret);
            }

            return(ret);
        }
        // simple cases made by a number followed an unit
        private DTParseResult ParseNumerWithUnit(string text, DateObject referenceTime)
        {
            var ret     = new DTParseResult();
            var numStr  = string.Empty;
            var unitStr = string.Empty;

            // if there are spaces between nubmer and unit
            var ers = this.config.CardinalExtractor.Extract(text);

            if (ers.Count == 1)
            {
                var pr      = this.config.NumberParser.Parse(ers[0]);
                var srcUnit = text.Substring(ers[0].Start + ers[0].Length ?? 0).Trim().ToLower();
                if (this.config.UnitMap.ContainsKey(srcUnit))
                {
                    numStr  = pr.Value.ToString();
                    unitStr = this.config.UnitMap[srcUnit];

                    ret.Timex       = "P" + (IsLessThanDay(unitStr) ? "T" : "") + numStr + unitStr[0];
                    ret.FutureValue = ret.PastValue = (double)pr.Value * this.config.UnitValueMap[srcUnit];
                    ret.Success     = true;
                    return(ret);
                }
            }

            // if there are NO spaces between number and unit
            var match = this.config.NumberCombinedWithUnit.Match(text);

            if (match.Success)
            {
                numStr = match.Groups["num"].Value;
                var srcUnit = match.Groups["unit"].Value.ToLower();
                if (this.config.UnitMap.ContainsKey(srcUnit))
                {
                    unitStr = this.config.UnitMap[srcUnit];

                    ret.Timex       = "P" + (IsLessThanDay(unitStr) ? "T" : "") + numStr + unitStr[0];
                    ret.FutureValue = ret.PastValue = double.Parse(numStr) * this.config.UnitValueMap[srcUnit];
                    ret.Success     = true;
                    return(ret);
                }
            }

            match = this.config.AnUnitRegex.Match(text);
            if (match.Success)
            {
                numStr = "1";
                var srcUnit = match.Groups["unit"].Value.ToLower();
                if (this.config.UnitMap.ContainsKey(srcUnit))
                {
                    unitStr = this.config.UnitMap[srcUnit];

                    ret.Timex       = "P" + (IsLessThanDay(unitStr) ? "T" : "") + numStr + unitStr[0];
                    ret.FutureValue = ret.PastValue = double.Parse(numStr) * this.config.UnitValueMap[srcUnit];
                    ret.Success     = true;
                    return(ret);
                }
            }

            return(ret);
        }
Exemple #8
0
        private DTParseResult Match2Date(Match match, DateObject referenceDate)
        {
            var ret        = new DTParseResult();
            var holidayStr = this.config.SanitizeHolidayToken(match.Groups["holiday"].Value.ToLowerInvariant());

            // get year (if exist)
            var yearStr  = match.Groups["year"].Value.ToLower();
            var orderStr = match.Groups["order"].Value.ToLower();
            int year;
            var hasYear = false;

            if (!string.IsNullOrEmpty(yearStr))
            {
                year    = int.Parse(yearStr);
                hasYear = true;
            }
            else if (!string.IsNullOrEmpty(orderStr))
            {
                var swift = this.config.GetSwiftYear(orderStr);
                if (swift < -1)
                {
                    return(ret);
                }
                year    = referenceDate.Year + swift;
                hasYear = true;
            }
            else
            {
                year = referenceDate.Year;
            }

            string holidayKey = string.Empty;

            foreach (var holidayPair in this.config.HolidayNames)
            {
                if (holidayPair.Value.Contains(holidayStr))
                {
                    holidayKey = holidayPair.Key;
                    break;
                }
            }

            var timexStr = string.Empty;

            if (!string.IsNullOrEmpty(holidayKey))
            {
                var value = referenceDate;
                Func <int, DateObject> function;
                if (this.config.HolidayFuncDictionary.TryGetValue(holidayKey, out function))
                {
                    value = function(year);
                    this.config.VariableHolidaysTimexDictionary.TryGetValue(holidayKey, out timexStr);
                    if (string.IsNullOrEmpty(timexStr))
                    {
                        timexStr = $"-{value.Month:D2}-{value.Day:D2}";
                    }
                }
                if (function == null)
                {
                    return(ret);
                }

                if (hasYear)
                {
                    ret.Timex       = year.ToString("D4") + timexStr;
                    ret.FutureValue = ret.PastValue = new DateObject(year, value.Month, value.Day);
                    ret.Success     = true;
                    return(ret);
                }
                ret.Timex       = "XXXX" + timexStr;
                ret.FutureValue = GetFutureValue(value, referenceDate, holidayKey);
                ret.PastValue   = GetPastValue(value, referenceDate, holidayKey);
                ret.Success     = true;
                return(ret);
            }
            return(ret);
        }