public override List <ParsedResult> Refine(string originalText, List <ParsedResult> results, Option opt)
        {
            if (results.Count < 2)
            {
                return(results);
            }

            var          mergedResult = new List <ParsedResult>();
            ParsedResult currResult   = null;
            ParsedResult prevResult   = null;

            for (var i = 1; i < results.Count; i++)
            {
                currResult = results[i];
                prevResult = results[i - 1];

                if (prevResult.End == null && currResult.End == null &&
                    IsAbleToMerge(originalText, prevResult, currResult))
                {
                    prevResult = this.MergeResult(originalText, prevResult, currResult);
                    currResult = null;
                    i         += 1;
                }

                mergedResult.Add(prevResult);
            }

            if (currResult != null)
            {
                mergedResult.Add(currResult);
            }


            return(mergedResult);
        }
        private void SetStartEndDates(ParsedResult result, DateTime date, DateTime reference)
        {
            ParsedComponents pivot = null;
            ParsedComponents node  = null;

            result.End = result.End ?? result.Start.Clone() as ParsedComponents;

            if (Config.Direction == DateTimeDirection.Backward)
            {
                pivot = result.End;
                node  = result.Start;
            }
            else
            {
                pivot = result.Start;
                node  = result.End;
            }
            pivot.Imply("year", reference.Year);
            pivot.Imply("month", reference.Month);
            pivot.Imply("day", reference.Day);
            pivot.Imply("hour", reference.Hour);
            pivot.Imply("minute", reference.Minute);
            pivot.Imply("second", reference.Second);

            node.Imply("year", date.Year);
            node.Imply("month", date.Month);
            node.Imply("day", date.Day);
            node.Imply("hour", date.Hour);
            node.Imply("minute", date.Minute);
            node.Imply("second", date.Second);

            result.Tags[this.GetType().Name] = true;
        }
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var text = match.Value.Trim();

            if (String.IsNullOrWhiteSpace(text))
            {
                return(null);
            }
            var result = new ParsedResult(new TemporalResult {
                Index = match.Index, Text = text, Reference = reference
            });
            int year;

            if (int.TryParse(text, out year))
            {
                result.Start.Assign("day", 1);
                result.Start.Assign("month", 1);
                result.Start.Assign("year", year);
                result.End = result.Start.Clone() as ParsedComponents;
                result.End.Assign("month", 12);
                result.Tags[this.GetType().Name] = true;
            }
            else
            {
                return(null);
            }

            return(result);
        }
Beispiel #4
0
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var text   = match.Groups[0].Value.Substring(match.Groups[1].Length);
            var index  = match.Index + match.Groups[1].Length;
            var result = new ParsedResult(new TemporalResult {
                Index = index, Text = text, Reference = reference
            });
            var refMoment   = GetMoment(reference);
            var startMoment = GetMoment(reference);
            var lowerText   = text.ToLower();

            if (String.Compare(lowerText, "tonight") == 0)
            {
                // Normally means this coming midnight
                result.Start.Imply("hour", 22);
                result.Start.Imply("meridiem", 1);
            }
            else if (new Regex("^tomorrow|^tmr").Match(lowerText).Success)
            {
                // Check not "Tomorrow" on late night
                if (refMoment.Hour > 1)
                {
                    startMoment.Day += 1;
                }
            }
            else if (new Regex("^yesterday").Match(lowerText).Success)
            {
                startMoment.Day -= 1;
            }
            else if (new Regex(@"last\s*night").Match(lowerText).Success)
            {
                result.Start.Imply("hour", 0);
                if (refMoment.Hour > 6)
                {
                    startMoment.Day -= 1;;
                }
            }
            else if (new Regex("now", RegexOptions.IgnoreCase).Match(lowerText).Success)
            {
                result.Start.Assign("hour", refMoment.Hour);
                result.Start.Assign("minute", refMoment.Minute);
                result.Start.Assign("second", refMoment.Second);
                result.Start.Assign("millisecond", refMoment.Millisecond);
            }

            result.Start.Assign("day", startMoment.Day);
            result.Start.Assign("month", startMoment.Month);
            result.Start.Assign("year", startMoment.Year);
            result.Tags["ENCasualDateParser"] = true;
            return(result);
        }
        private bool IsAbleToMerge(string text, ParsedResult result1, ParsedResult result2)
        {
            var    begin       = result1.Index + result1.Text.Length;
            var    end         = result2.Index;
            string textBetween = String.Empty;

            if (end > begin)
            {
                textBetween = text.Substring(begin, (end - begin));
            }
            else
            {
                textBetween = text.Substring(end, (begin - end)); //swap
            }
            return(Pattern.Match(textBetween).Success);
        }
Beispiel #6
0
        protected void PredictAppropriateYear(DateTime?reference, int month, int day, ref ParsedResult result)
        {
            var refMoment = new DateTime(reference.Value.Year, month, day);
            var nextYear  = new DateTime(refMoment.Year + 1, refMoment.Month, refMoment.Day);
            var lastYear  = new DateTime(refMoment.Year - 1, refMoment.Month, refMoment.Day);
            var distanceToCurrentYearDate  = (refMoment - reference.Value).TotalHours;
            var distanceToNextYearDate     = (nextYear - reference.Value).TotalHours;
            var distanceToPreviousYearDate = (lastYear - reference.Value).TotalHours;

            if (Config.Direction == DateTimeDirection.Default)
            {
                //set the year based on nearest of the 3 dates from now
                //- the one in previous year
                //- the one in current year
                //- the one in next year
                if (Math.Abs(distanceToNextYearDate) < Math.Abs(distanceToCurrentYearDate))
                {
                    refMoment = nextYear;
                }
                else if (Math.Abs(distanceToPreviousYearDate) < Math.Abs(distanceToCurrentYearDate))
                {
                    refMoment = lastYear;
                }
            }
            //if distance to current year is positive with always-backward config, set to last year, else set to current year
            else if (Config.Direction == DateTimeDirection.Backward && distanceToCurrentYearDate > 0)
            {
                refMoment = lastYear;
            }
            //if distance to current year is negative with always-forward config, set to next year, else set to current year
            else if (Config.Direction == DateTimeDirection.Forward && distanceToCurrentYearDate < 0)
            {
                refMoment = nextYear;
            }


            result.Start.Assign("day", day);
            result.Start.Assign("month", month);
            result.Start.Imply("year", refMoment.Year);
        }
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var index = match.Index + match.Groups[1].Length;
            var text  = match.Groups[0].Value.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length);

            var result = new ParsedResult(new TemporalResult
            {
                Text      = text,
                Index     = index,
                Reference = reference
            });

            var           numStr = match.Groups[3].Value.ToLower();
            INTEGER_WORDS numEnum;
            int           num = -1;

            if (Enum.TryParse(numStr, true, out numEnum) && Enum.IsDefined(typeof(INTEGER_WORDS), numEnum))
            {
                num = (int)numEnum;
            }
            else if (String.Compare(numStr, "a", true) == 0 || String.Compare(numStr, "an", true) == 0)
            {
                num = 1;
            }
            else if (new Regex("few", RegexOptions.IgnoreCase).Match(numStr).Success)
            {
                num = 3;
            }
            else if (new Regex("half", RegexOptions.IgnoreCase).Match(numStr).Success)
            { //let's take care of half if the requirement comes!
              //num = 0.5;
            }
            else
            {
                int.TryParse(numStr, out num); //failed int.parse => num = 0
            }

            DateTime date = new DateTime(reference.Value.Year, reference.Value.Month, reference.Value.Day);

            if (new Regex("day|week|month|year", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
            {
                if (new Regex("day", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
                {
                    if (Config.Direction == DateTimeDirection.Backward)
                    {
                        date = date.AddDays(-num);
                    }
                    else
                    {
                        date = date.AddDays(num);
                    }
                }
                else if (new Regex("week", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
                {
                    if (Config.Direction == DateTimeDirection.Backward)
                    {
                        date = date.AddDays(-num * 7);
                    }
                    else
                    {
                        date = date.AddDays(num * 7);
                    }
                }
                else if (new Regex("month", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
                {
                    if (Config.Direction == DateTimeDirection.Backward)
                    {
                        date = date.AddMonths(-num);
                    }
                    else
                    {
                        date = date.AddMonths(num);
                    }
                }
                else if (new Regex("year", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
                {
                    if (Config.Direction == DateTimeDirection.Backward)
                    {
                        date = date.AddYears(-num);
                    }
                    else
                    {
                        date = date.AddYears(num);
                    }
                }
            }
            else if (new Regex("hour", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
            {
                if (Config.Direction == DateTimeDirection.Backward)
                {
                    date = date.AddHours(-num);
                }
                else
                {
                    date = date.AddHours(num);
                }
            }
            else if (new Regex("min", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
            {
                if (Config.Direction == DateTimeDirection.Backward)
                {
                    date = date.AddMinutes(-num);
                }
                else
                {
                    date = date.AddMinutes(num);
                }
            }
            else if (new Regex("second", RegexOptions.IgnoreCase).Match(match.Groups[4].Value).Success)
            {
                if (Config.Direction == DateTimeDirection.Backward)
                {
                    date = date.AddSeconds(-num);
                }
                else
                {
                    date = date.AddSeconds(num);
                }
            }

            SetStartEndDates(result, date, reference ?? DateTime.Now);
            return(result);
        }
        private ParsedResult MergeResult(string text, ParsedResult fromResult, ParsedResult toResult)
        {
            if (!IsWeekdayResult(fromResult) && !IsWeekdayResult(toResult))
            {
                foreach (var kvp in toResult.Start.knownValues)
                {
                    if (!fromResult.Start.IsCertain(kvp.Key))
                    {
                        fromResult.Start.Assign(kvp.Key, toResult.Start.GetValue(kvp.Key));
                    }
                }

                foreach (var kvp in fromResult.Start.knownValues)
                {
                    if (!toResult.Start.IsCertain(kvp.Key))
                    {
                        toResult.Start.Assign(kvp.Key, fromResult.Start.GetValue(kvp.Key));
                    }
                }
            }

            if (fromResult.Start.Date > toResult.Start.Date)
            {
                var fromMoment = fromResult.Start.Date;
                var toMoment   = toResult.Start.Date;

                if (IsWeekdayResult(fromResult) && fromMoment.AddDays(-7) < toMoment)
                {
                    fromMoment = fromMoment.AddDays(-7);
                    fromResult.Start.Imply("day", fromMoment.Day);
                    fromResult.Start.Imply("month", fromMoment.Month);
                    fromResult.Start.Imply("year", fromMoment.Year);
                }
                else if (this.IsWeekdayResult(toResult) && toMoment.AddDays(7) > fromMoment)
                {
                    toMoment = toMoment.AddDays(7);
                    toResult.Start.Imply("day", toMoment.Day);
                    toResult.Start.Imply("month", toMoment.Month);
                    toResult.Start.Imply("year", toMoment.Year);
                }
                else
                {
                    var tmp = toResult;
                    toResult   = fromResult;
                    fromResult = tmp;
                }
            }

            fromResult.End = toResult.Start;



            foreach (var tag in toResult.Tags)
            {
                fromResult.Tags[tag.Key] = true;
            }


            var startIndex = Math.Min(fromResult.Index, toResult.Index);
            var endIndex   = Math.Max(
                fromResult.Index + fromResult.Text.Length,
                toResult.Index + toResult.Text.Length);

            fromResult.Index = startIndex;
            fromResult.Text  = text.Substring(startIndex, (endIndex - startIndex));
            fromResult.Tags["ENMergeDateTimeRefiner"] = true;
            return(fromResult);
        }
 private bool IsWeekdayResult(ParsedResult result)
 {
     return(result.Start.IsCertain("weekday") && !result.Start.IsCertain("day"));
 }
Beispiel #10
0
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            // This pattern can be overlaped Ex. [12] AM, 1[2] AM
            if (match.Index > 0 && new Regex(@"/\w/", RegexOptions.IgnoreCase).Match(originalText[match.Index - 1].ToString()).Success)
            {
                return(null);
            }

            int    index  = match.Index + match.Groups[1].Length;
            string text   = match.Groups[0].Value.Substring(match.Groups[1].Length);
            var    result = new ParsedResult(new TemporalResult
            {
                Text      = text,
                Index     = index,
                Reference = reference
            });

            result.Tags["ENTimeExpressionParser"] = true;

            result.Start.Imply("day", reference.Value.Day);
            result.Start.Imply("month", reference.Value.Month);
            result.Start.Imply("year", reference.Value.Year);

            var hour     = 0;
            var minute   = 0;
            var meridiem = -1;

            // ----- Millisecond
            if (match.Groups[MILLI_SECOND_GROUP].Captures.Count != 0)
            {
                int millisecond = 0;
                int.TryParse(match.Groups[MILLI_SECOND_GROUP].Value.Substring(0, 3), out millisecond);
                if (millisecond >= 1000)
                {
                    return(null);
                }

                result.Start.Assign("millisecond", millisecond);
            }

            // ----- Second
            if (match.Groups[SECOND_GROUP].Captures.Count != 0)
            {
                int second = 0;
                int.TryParse(match.Groups[SECOND_GROUP].Value, out second);
                if (second >= 60)
                {
                    return(null);
                }

                result.Start.Assign("second", second);
            }

            // ----- Hours
            if (String.Compare(match.Groups[HOUR_GROUP].Value.ToLower(), "noon", true) == 0)
            {
                meridiem = 1;
                hour     = 12;
            }
            else if (String.Compare(match.Groups[HOUR_GROUP].Value.ToLower(), "midnight", true) == 0)
            {
                meridiem = 0;
                hour     = 0;
            }
            else
            {
                int.TryParse(match.Groups[HOUR_GROUP].Value, out hour);
            }

            // ----- Minutes
            if (match.Groups[MINUTE_GROUP].Captures.Count != 0)
            {
                int.TryParse(match.Groups[MINUTE_GROUP].Value, out minute);
            }
            else if (hour > 100)
            {
                minute = hour % 100;
                hour   = (int)(hour / 100);
            }

            if (minute >= 60)
            {
                return(null);
            }

            if (hour > 24)
            {
                return(null);
            }
            if (hour >= 12)
            {
                meridiem = 1;
            }

            // ----- AM & PM
            if (match.Groups[AM_PM_HOUR_GROUP].Captures.Count != 0)
            {
                if (hour > 12)
                {
                    return(null);
                }
                var ampm = match.Groups[AM_PM_HOUR_GROUP].Captures[0].Value.ToLower();
                if (String.Compare(ampm, "a", true) == 0)
                {
                    meridiem = 0;
                    if (hour == 12)
                    {
                        hour = 0;
                    }
                }

                if (String.Compare(ampm, "p", true) == 0)
                {
                    meridiem = 1;
                    if (hour != 12)
                    {
                        hour += 12;
                    }
                }
            }

            result.Start.Assign("hour", hour);
            result.Start.Assign("minute", minute);

            if (meridiem >= 0)
            {
                result.Start.Assign("meridiem", meridiem);
            }
            else
            {
                if (hour < 12)
                {
                    result.Start.Imply("meridiem", 0);
                }
                else
                {
                    result.Start.Imply("meridiem", 1);
                }
            }

            // ==============================================================
            //                  Extracting the "to" chunk
            // ==============================================================
            match = SECOND_REG_PATTERN.Match(originalText.Substring(result.Index + result.Text.Length));
            if (!match.Success)
            {
                // Not accept number only result
                if (new Regex(@"/^\d+$/", RegexOptions.IgnoreCase).Match(result.Text).Success)
                {
                    return(null);
                }
                return(result);
            }



            // Pattern "YY.YY -XXXX" is more like timezone offset
            if (new Regex((@"/^\s*(\+|\-)\s*\d{3,4}$/"), RegexOptions.IgnoreCase).Match(match.Groups[0].Value).Success)
            {
                return(result);
            }

            if (result.End == null)
            {
                result.End = new ParsedComponents(null, result.Start.Date);
            }

            hour     = 0;
            minute   = 0;
            meridiem = -1;

            // ----- Millisecond
            if (match.Groups[MILLI_SECOND_GROUP].Captures.Count != 0)
            {
                int millisecond;
                int.TryParse(match.Groups[MILLI_SECOND_GROUP].Value.Substring(0, 3), out millisecond);
                if (millisecond >= 1000)
                {
                    return(null);
                }

                result.End.Assign("millisecond", millisecond);
            }

            // ----- Second
            if (match.Groups[SECOND_GROUP].Captures.Count != 0)
            {
                int second;
                int.TryParse(match.Groups[SECOND_GROUP].Value, out second);
                if (second >= 60)
                {
                    return(null);
                }

                result.End.Assign("second", second);
            }

            int.TryParse(match.Groups[2].Value, out hour);

            // ----- Minute
            if (match.Groups[MINUTE_GROUP].Captures.Count != 0)
            {
                int.TryParse(match.Groups[MINUTE_GROUP].Value, out minute);
                if (minute >= 60)
                {
                    return(result);
                }
            }
            else if (hour > 100)
            {
                minute = hour % 100;
                hour   = (int)(hour / 100);
            }

            if (minute >= 60)
            {
                return(null);
            }

            if (hour > 24)
            {
                return(null);
            }
            if (hour >= 12)
            {
                meridiem = 1;
            }

            // ----- AM & PM
            if (match.Groups[AM_PM_HOUR_GROUP].Captures.Count != 0)
            {
                if (hour > 12)
                {
                    return(null);
                }

                var ampm = match.Groups[AM_PM_HOUR_GROUP].Captures[0].Value.ToLower();
                if (String.Compare(ampm, "a", true) == 0)
                {
                    meridiem = 0;
                    if (hour == 12)
                    {
                        hour = 0;
                        if (!result.End.IsCertain("day"))
                        {
                            result.End.Imply("day", result.End.GetValue("day") + 1);
                        }
                    }
                }

                if (ampm == "p")
                {
                    meridiem = 1;
                    if (hour != 12)
                    {
                        hour += 12;
                    }
                }

                if (!result.Start.IsCertain("meridiem"))
                {
                    if (meridiem == 0)
                    {
                        result.Start.Imply("meridiem", 0);

                        if (result.Start.GetValue("hour") == 12)
                        {
                            result.Start.Assign("hour", 0);
                        }
                    }
                    else
                    {
                        result.Start.Imply("meridiem", 1);

                        if (result.Start.GetValue("hour") != 12)
                        {
                            result.Start.Assign("hour", result.Start.GetValue("hour") + 12);
                        }
                    }
                }
            }

            result.Text = result.Text + match.Groups[0].Value;
            result.End.Assign("hour", hour);
            result.End.Assign("minute", minute);
            if (meridiem >= 0)
            {
                result.End.Assign("meridiem", meridiem);
            }
            else
            {
                var startAtPM = result.Start.IsCertain("meridiem") && result.Start.GetValue("meridiem") == 1;
                if (startAtPM && result.Start.GetValue("hour") > hour)
                {
                    // 10pm - 1 (am)
                    result.End.Imply("meridiem", 0);
                }
                else if (hour > 12)
                {
                    result.End.Imply("meridiem", 1);
                }
            }

            if (result.End.Date < result.Start.Date)
            {
                result.End.Imply("day", result.End.GetValue("day") + 1);
            }

            return(result);
        }
Beispiel #11
0
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var text   = match.Groups[0].Value.Substring(match.Groups[1].Length);
            var index  = match.Index + match.Groups[1].Length;
            var result = new ParsedResult(new TemporalResult {
                Index = index, Text = text, Reference = reference
            });
            var    refMoment   = GetMoment(reference);
            var    startMoment = GetMoment(reference);
            Moment endMoment   = null;
            var    lowerText   = text.ToLower();

            if (new Regex(@"(\W|^)(latest|recent)|((last|latest|recent|previous)?\s*months?)").Match(lowerText).Success)
            {
                startMoment.Month -= 1;
                if (startMoment.Month == 0) //move to last year
                {
                    startMoment.Year -= 1;
                }
            }
            else if (new Regex(@"(\W|^)(latest|recent)|((last|latest|recent|previous)\s*quarters?)").Match(lowerText).Success)
            {
                SetDateRangeForQuarterOffset(-1, ref startMoment, ref endMoment);
            }
            else if (new Regex(@"(\W|^)(current|present)|((this|current|present)\s*quarters?)").Match(lowerText).Success)
            {
                SetDateRangeForQuarterOffset(-1, ref startMoment, ref endMoment);
            }
            else if (new Regex(@"(\W|^)((last|latest|recent|previous)\s*years?)").Match(lowerText).Success)
            {
                startMoment.Year -= 1;
                startMoment.Month = 1;
                endMoment         = GetMoment(startMoment.DateTime());
                endMoment.Month   = 12;
            }
            else if (new Regex(@"(\W|^)((this|current|present)\s*years?)").Match(lowerText).Success)
            {
                startMoment.Month = 1;
                endMoment         = GetMoment(startMoment.DateTime());
                endMoment.Month   = 12;
            }
            else if (new Regex(@"(\W|^)(annual|trends?|evolutions?|movements?|progressions?)").Match(lowerText).Success)
            {
                //last 12 months
                startMoment.Year -= 1;
                endMoment         = GetMoment(startMoment.DateTime());
                endMoment.Month  += 11;
                if (endMoment.Month > 12)
                {
                    //move to next year
                    endMoment.Year  += 1;
                    endMoment.Month -= 12;
                }
            }
            else if (match.Groups[7].Captures.Count > 0) //things like 3rd,4th.. comes in 7th group
            {
                int qrtr;
                var qrtrStr = match.Groups[7].Value.Trim().Replace('_', ' ').ToLower();
                if (int.TryParse(qrtrStr, out qrtr))
                {
                    SetDateRangeForQuarterIndex(qrtr, ref startMoment, ref endMoment);
                }
            }
            else if (match.Groups[6].Captures.Count > 0) //ordinal number comes in 6th group
            {
                var           ordinalStr = match.Groups[6].Value.Trim().Replace('_', ' ').ToLower();
                ORDINAL_WORDS ordinalEnum;
                if (Enum.TryParse(ordinalStr, true, out ordinalEnum) && Enum.IsDefined(typeof(ORDINAL_WORDS), ordinalEnum))
                {
                    SetDateRangeForQuarterIndex((int)ordinalEnum, ref startMoment, ref endMoment);
                }
            }


            result.Start.Assign("day", startMoment.Day);
            result.Start.Assign("month", startMoment.Month);
            result.Start.Assign("year", startMoment.Year);
            if (endMoment != null)
            {
                result.End = result.End ?? result.Start.Clone() as ParsedComponents;
                result.End.Assign("day", endMoment.Day);
                result.End.Assign("month", endMoment.Month);
                result.End.Assign("year", endMoment.Year);
            }
            result.Tags[this.GetType().Name] = true;
            return(result);
        }
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var text  = match.Groups[0].Value.Substring(match.Groups[1].Length);
            var index = match.Index + match.Groups[1].Length;

            var result = new ParsedResult(new TemporalResult
            {
                Text      = text,
                Index     = index,
                Reference = reference
            });

            result.Start.Assign("year", int.Parse(match.Groups[YEAR_NUMBER_GROUP].Value));
            result.Start.Assign("month", int.Parse(match.Groups[MONTH_NUMBER_GROUP].Value));
            result.Start.Assign("day", int.Parse(match.Groups[DATE_NUMBER_GROUP].Value));

            //validation
            if (result.Start.GetValue("month") > 12 || result.Start.GetValue("month") < 1 ||
                result.Start.GetValue("day") > 31 || result.Start.GetValue("day") < 1)
            {
                return(null);
            }

            if (!String.IsNullOrWhiteSpace(match.Groups[HOUR_NUMBER_GROUP].Value))
            {
                result.Start.Assign("hour",
                                    int.Parse(match.Groups[HOUR_NUMBER_GROUP].Value));
                result.Start.Assign("minute",
                                    int.Parse(match.Groups[MINUTE_NUMBER_GROUP].Value));

                if (!String.IsNullOrWhiteSpace(match.Groups[SECOND_NUMBER_GROUP].Value))
                {
                    result.Start.Assign("second",
                                        int.Parse(match.Groups[SECOND_NUMBER_GROUP].Value));
                }

                if (!String.IsNullOrWhiteSpace(match.Groups[MILLISECOND_NUMBER_GROUP].Value))
                {
                    result.Start.Assign("millisecond",
                                        int.Parse(match.Groups[MILLISECOND_NUMBER_GROUP].Value));
                }

                if (!String.IsNullOrWhiteSpace(match.Groups[TZD_HOUR_OFFSET_GROUP].Value))
                {
                    result.Start.Assign("timezoneOffset", 0);
                }
                else
                {
                    var minuteOffset = 0;
                    var hourOffset   = int.Parse(match.Groups[TZD_HOUR_OFFSET_GROUP].Value);
                    if (!String.IsNullOrWhiteSpace(match.Groups[TZD_MINUTE_OFFSET_GROUP].Value))
                    {
                        minuteOffset = int.Parse(match.Groups[TZD_MINUTE_OFFSET_GROUP].Value);
                    }

                    var offset = hourOffset * 60;
                    if (offset < 0)
                    {
                        offset -= minuteOffset;
                    }
                    else
                    {
                        offset += minuteOffset;
                    }

                    result.Start.Assign("timezoneOffset", offset);
                }
            }

            result.Tags["ENISOFormatParser"] = true;
            return(result);
        }
Beispiel #13
0
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var text   = match.Groups[0].Value.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length);
            var index  = match.Index + match.Groups[1].Length;
            var result = new ParsedResult(new TemporalResult
            {
                Text      = text,
                Index     = index,
                Reference = reference
            });

            var          monthStr = match.Groups[MONTH_NAME_GROUP].Value.ToLower();
            MONTH_OFFSET monthEnum;
            int          month = -1;

            if (Enum.TryParse(monthStr, true, out monthEnum) && Enum.IsDefined(typeof(MONTH_OFFSET), monthEnum))
            {
                month = (int)monthEnum;
            }
            else
            {
                int.TryParse(monthStr, out month);
            }

            string        dayStr = null;
            ORDINAL_WORDS dayEnum;
            int           day = -1;

            if (match.Groups[DATE_NUM_GROUP].Captures.Count != 0)
            {
                dayStr = match.Groups[DATE_NUM_GROUP].Value.ToLower();

                if (Enum.TryParse(dayStr, true, out dayEnum) && Enum.IsDefined(typeof(MONTH_OFFSET), dayEnum))
                {
                    day = (int)dayEnum;
                }
                else
                {
                    int.TryParse(dayStr, out day);
                }
            }
            else
            {
                dayStr = match.Groups[DATE_GROUP].Value.Trim().Replace('_', ' ').ToLower();
                if (Enum.TryParse(dayStr, true, out dayEnum) && Enum.IsDefined(typeof(ORDINAL_WORDS), dayEnum))
                {
                    day = (int)dayEnum;
                }
            }

            string yearStr = null;
            int    year    = -1;

            if (match.Groups[YEAR_GROUP].Captures.Count != 0)
            {
                yearStr = match.Groups[YEAR_GROUP].Value;

                if (new Regex("BE", RegexOptions.IgnoreCase).Match(yearStr).Success)
                {
                    // Buddhist Era
                    yearStr = Regex.Replace(yearStr, "BE", String.Empty, RegexOptions.IgnoreCase);
                    int.TryParse(yearStr, out year);
                    year -= 543;
                }
                else if (new Regex("BC", RegexOptions.IgnoreCase).Match(yearStr).Success)
                {
                    // Before Christ
                    yearStr = Regex.Replace(yearStr, "BC", String.Empty, RegexOptions.IgnoreCase);
                    int.TryParse(yearStr, out year);
                    year *= -1;
                }
                else if (new Regex("AD", RegexOptions.IgnoreCase).Match(yearStr).Success)
                {
                    yearStr = Regex.Replace(yearStr, "AD", String.Empty, RegexOptions.IgnoreCase);
                    int.TryParse(yearStr, out year);
                }
                else
                {
                    int.TryParse(yearStr, out year);
                    if (year < 100)
                    {
                        year = year + 2000;
                    }
                }
            }

            if (year != -1)
            {
                result.Start.Assign("day", day);
                result.Start.Assign("month", month);
                result.Start.Assign("year", year);
            }
            else
            {
                //Find the most appropriated year
                PredictAppropriateYear(reference, month, day, ref result);
            }

            // Weekday component
            if (match.Groups[WEEKDAY_GROUP].Captures.Count != 0)
            {
                var            weekdayStr = match.Groups[WEEKDAY_GROUP].Value.ToLower();
                WEEKDAY_OFFSET weekdayEnum;
                if (Enum.TryParse(weekdayStr, true, out weekdayEnum) && Enum.IsDefined(typeof(WEEKDAY_OFFSET), weekdayEnum))
                {
                    int weekday = (int)weekdayEnum;
                    result.Start.Assign("weekday", weekday);
                }
            }

            // Text can be 'range' value. Such as '12 - 13 January 2012'
            if (match.Groups[DATE_TO_GROUP].Captures.Count != 0)
            {
                string        endDateStr = match.Groups[DATE_TO_NUM_GROUP].Value;
                int           endDate    = -1;
                ORDINAL_WORDS endDateEnum;
                if (match.Groups[DATE_TO_NUM_GROUP].Captures.Count != 0)
                {
                    int.TryParse(endDateStr, out endDate);
                }
                else if (Enum.TryParse(endDateStr.Trim().Replace('-', ' '), true, out endDateEnum) &&
                         Enum.IsDefined(typeof(WEEKDAY_OFFSET), endDateEnum))
                {
                    endDate = (int)endDateEnum;
                }

                result.End = (ParsedComponents)result.Start.Clone();
                result.End.Assign("day", endDate);
            }

            result.Tags["ENMonthNameLittleEndianParser"] = true;
            return(result);
        }
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            var index = match.Index + match.Groups[1].Length;
            var text  = match.Groups[0].Value.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length);

            var result = new ParsedResult(new TemporalResult
            {
                Text      = text,
                Index     = index,
                Reference = reference
            });

            int          month    = -1;
            var          monthStr = match.Groups[MONTH_NAME_GROUP].Value.ToLower();
            MONTH_OFFSET monthEnum;

            if (Enum.TryParse(monthStr, true, out monthEnum) && Enum.IsDefined(typeof(MONTH_OFFSET), monthEnum))
            {
                month = (int)monthEnum;
            }
            var    day     = 1;
            int    year    = -1;
            string yearStr = null;

            if (match.Groups[YEAR_GROUP].Captures.Count != 0)
            {
                yearStr = match.Groups[YEAR_GROUP].Value;
                int.TryParse(yearStr, out year);

                if (match.Groups[YEAR_BE_GROUP].Captures.Count != 0)
                {
                    if (new Regex("BE", RegexOptions.IgnoreCase).IsMatch(match.Groups[YEAR_BE_GROUP].Value))
                    {
                        // Buddhist Era
                        year = year - 543;
                    }
                    else if (new Regex("BC", RegexOptions.IgnoreCase).IsMatch(match.Groups[YEAR_BE_GROUP].Value))
                    {
                        // Before Christ
                        year = -year;
                    }
                }
                else if (year < 100)
                {
                    year = year + 2000;
                }
            }

            if (year != -1)
            {
                result.Start.Imply("day", day);
                result.Start.Assign("month", month);
                result.Start.Assign("year", year);
            }
            else
            {
                //Find the most appropriated year
                PredictAppropriateYear(reference, month, day, ref result);
            }

            result.Tags["ENMonthNameParser"] = true;
            return(result);
        }
        protected override ParsedResult Extract(string originalText, DateTime?reference, Match match, Option opt)
        {
            if (match.Index > 0 && new Regex(@"/\w/").Match(originalText[match.Index - 1].ToString()).Success)
            {
                return(null);
            }

            var text = match.Groups[0].Value;

            text = text.Substring(match.Groups[1].Length, match.Groups[0].Length - match.Groups[1].Length);
            int index = match.Index + match.Groups[1].Length;

            var result = new ParsedResult(new TemporalResult
            {
                Text      = text,
                Index     = index,
                Reference = reference
            });

            var fragments = Util.ExtractDateTimeUnitFragments(match.Groups[2].Value);
            var date      = new DateTime(reference.Value.Year, reference.Value.Month, reference.Value.Day);

            foreach (var kvp in fragments)
            {
                switch (kvp.Key)
                {
                case TEMPORAL_COMPONENT.Year:
                    date = date.AddYears(-kvp.Value);
                    break;

                case TEMPORAL_COMPONENT.Month:
                    date = date.AddMonths(-kvp.Value);
                    break;

                case TEMPORAL_COMPONENT.Day:
                    date = date.AddDays(-kvp.Value);
                    break;

                case TEMPORAL_COMPONENT.Hour:
                    date = date.AddHours(-kvp.Value);
                    break;

                case TEMPORAL_COMPONENT.Minute:
                    date = date.AddMinutes(-kvp.Value);
                    break;

                case TEMPORAL_COMPONENT.Second:
                    date = date.AddSeconds(-kvp.Value);
                    break;

                case TEMPORAL_COMPONENT.Week:
                    date = date.AddDays(-kvp.Value * 7);
                    break;

                default:
                    break;
                }
            }

            if ((fragments.ContainsKey(TEMPORAL_COMPONENT.Hour) && fragments[TEMPORAL_COMPONENT.Hour] > 0) ||
                (fragments.ContainsKey(TEMPORAL_COMPONENT.Minute) && fragments[TEMPORAL_COMPONENT.Minute] > 0) ||
                (fragments.ContainsKey(TEMPORAL_COMPONENT.Second) && fragments[TEMPORAL_COMPONENT.Second] > 0))
            {
                result.Start.Assign("hour", date.Hour);
                result.Start.Assign("minute", date.Minute);
                result.Start.Assign("second", date.Second);
                result.Tags["ENTimeAgoFormatParser"] = true;
            }

            if ((fragments.ContainsKey(TEMPORAL_COMPONENT.Day) && fragments[TEMPORAL_COMPONENT.Day] > 0) ||
                (fragments.ContainsKey(TEMPORAL_COMPONENT.Month) && fragments[TEMPORAL_COMPONENT.Month] > 0) ||
                (fragments.ContainsKey(TEMPORAL_COMPONENT.Year) && fragments[TEMPORAL_COMPONENT.Year] > 0))
            {
                result.Start.Assign("day", date.Day);
                result.Start.Assign("month", date.Month);
                result.Start.Assign("year", date.Year);
            }
            else
            {
                if (fragments.ContainsKey(TEMPORAL_COMPONENT.Week) && fragments[TEMPORAL_COMPONENT.Week] > 0)
                {
                    result.Start.Imply("weekday", date.Day);
                }

                result.Start.Imply("day", date.Day);
                result.Start.Imply("month", date.Month);
                result.Start.Imply("year", date.Year);
            }

            return(result);
        }