示例#1
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            var token = data.Tokens[match.Index];

            data.RemoveRange(match.Index, 1);

            if (Morph.HasLemma(token.Value, Keywords.Holiday[0], Morph.LemmaSearchOptions.OnlySingular))
            {
                // singular
                var saturday = new TextToken(Keywords.Saturday[0])
                {
                    Start = token.Start,
                    End   = token.End
                };
                data.ReturnTokens(match.Index, "D", saturday);
            }
            else
            {
                // plural
                var holidays = new[] { Keywords.Saturday[0], Keywords.TimeTo[0], Keywords.Sunday[0] }
                .Select(k => new TextToken(k, token.Start, token.End))
                .ToArray();
                data.ReturnTokens(match.Index, "DtD", holidays);
            }

            return(true);
        }
示例#2
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            if (match.Groups[1].Success || match.Groups[3].Success)
            {
                var hours = 0;
                switch (match.Groups[2].Value)
                {
                case "r":     // morning
                    hours = 9;
                    break;

                case "a":     // day
                case "d":
                case "n":     // noon
                    hours = 12;
                    break;

                case "v":     // evening
                    hours = 17;
                    break;

                case "g":     // night
                    hours = 23;
                    break;
                }

                if (hours != 0)
                {
                    var date = new AbstractPeriod
                    {
                        Time = new TimeSpan(hours, 0, 0)
                    };
                    date.Fix(FixPeriod.TimeUncertain);

                    // remove and insert
                    var startIndex = match.Index;
                    var length     = match.Length - 1; // skip date at the beginning or ar the end
                    if (match.Groups[1].Success)
                    {
                        // skip first date
                        startIndex++;
                        if (match.Groups[3].Success)
                        {
                            // skip both dates at the beginning and at the end
                            length--;
                        }
                    }
                    data.ReplaceTokensByDates(startIndex, length, date);

                    return(true);
                }
            }

            return(false);
        }
示例#3
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            var date = new AbstractPeriod();

            // day of week
            var dayOfWeek     = ParserUtils.FindIndex(data.Tokens[match.Groups[2].Index].Value, Keywords.DaysOfWeek()) + 1;
            var userDayOfWeek = (int)userDate.DayOfWeek;

            if (userDayOfWeek == 0)
            {
                userDayOfWeek = 7;                     // starts from Monday, not Sunday
            }
            var diff = dayOfWeek - userDayOfWeek;

            if (match.Groups[1].Success)
            {
                switch (match.Groups[1].Value)
                {
                case "y":     // "closest next"
                    if (diff < 0)
                    {
                        diff += 7;
                    }
                    date.Date = userDate.AddDays(diff);
                    break;

                case "x":     // "next"
                    date.Date = userDate.AddDays(diff + 7);
                    break;

                case "s":     // "previous"
                    date.Date = userDate.AddDays(diff - 7);
                    break;

                case "u":     // "current"
                    date.Date = userDate.AddDays(diff);
                    break;
                }
                date.FixDownTo(FixPeriod.Day);
            }
            else
            {
                date.Date = userDate.AddDays(diff);
                date.Fix(FixPeriod.Day);
                date.FixDayOfWeek = true;
            }

            // remove and insert
            data.ReplaceTokensByDates(match.Index, match.Length, date);

            return(true);
        }
示例#4
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            var date      = new AbstractPeriod();
            var direction = 0;

            // relative type
            switch (match.Groups[1].Value)
            {
            case "y":
            case "x":
                direction = 1;     // "next" or "closest next"
                break;

            case "s":
                direction = -1;
                break;
            }

            // time period type
            switch (match.Groups[2].Value)
            {
            case "Y":
                date.Date = userDate.AddYears(direction);
                date.Fix(FixPeriod.Year);
                break;

            case "m":
                date.Date = userDate.AddMonths(direction);
                date.FixDownTo(FixPeriod.Month);
                break;

            case "w":
                date.Date = userDate.AddDays(direction * 7);
                date.FixDownTo(FixPeriod.Week);
                break;

            case "d":
                date.Date = userDate.AddDays(direction);
                date.FixDownTo(FixPeriod.Day);
                break;
            }

            // remove and insert
            data.ReplaceTokensByDates(match.Index, match.Length, date);

            return(true);
        }
示例#5
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            var monthFixed = false;

            // parse month
            var mStr = data.Tokens[match.Groups[2].Index].Value;

            Console.WriteLine(mStr);
            var month = ParserUtils.FindIndex(mStr, Keywords.Months()) + 1;

            if (month == 0)
            {
                month = userDate.Month;             // # instead M
            }
            else
            {
                monthFixed = true;
            }

            // set for first date same month as for second, ignore second (will parse further)
            var t = data.Tokens[match.Groups[1].Index];

            int.TryParse(t.Value, out var day);

            // current token is number, store it as a day
            var period = new AbstractPeriod
            {
                Date = new DateTime(
                    userDate.Year,
                    month,
                    ParserUtils.GetDayValidForMonth(userDate.Year, month, day)
                    )
            };

            // fix from week to day, and year/month if it was
            period.Fix(FixPeriod.Week, FixPeriod.Day);
            if (monthFixed)
            {
                period.Fix(FixPeriod.Month);
            }

            // replace
            data.ReplaceTokensByDates(match.Groups[1].Index, 1, period);

            return(true);
        }
示例#6
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            // just year number
            int.TryParse(data.Tokens[match.Index].Value, out var n);
            var year = ParserUtils.GetYearFromNumber(n);

            // insert date
            var date = new AbstractPeriod
            {
                Date = new DateTime(year, 1, 1)
            };

            date.Fix(FixPeriod.Year);

            // remove and insert
            data.ReplaceTokensByDates(match.Index, match.Length, date);

            return(true);
        }
示例#7
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            if (!int.TryParse(match.Value, out var relativeDay))
            {
                return(false);
            }
            relativeDay -= 4;

            // create date
            var date = new AbstractPeriod
            {
                Date = userDate.AddDays(relativeDay)
            };

            date.FixDownTo(FixPeriod.Day);

            // remove and insert
            data.ReplaceTokensByDates(match.Index, match.Length, date);

            return(true);
        }
示例#8
0
 public void ParseTokens(DatesRawData data, DateTime userDate)
 {
     ForAllMatches(data.GetPattern, pattern: GetRegexPattern(), action: m => ParseMatch(data, m, userDate));
 }
示例#9
0
 protected abstract bool ParseMatch(DatesRawData data, Match match, DateTime userDate);
示例#10
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            var year      = userDate.Year;
            var yearFixed = false;

            // parse month
            var mStr  = data.Tokens[match.Index + match.Groups[1].Length].Value;
            var month = ParserUtils.FindIndex(mStr, Keywords.Months()) + 1;

            if (month == 0)
            {
                month = userDate.Month;
            }

            var monthPast   = month < userDate.Month;
            var monthFuture = month > userDate.Month;

            // check if relative
            if (match.Groups[1].Success)
            {
                switch (match.Groups[1].Value)
                {
                case "s":     // previous
                    if (!monthPast)
                    {
                        year--;
                    }
                    break;

                case "u":     // current
                    break;

                case "y":     // current-next
                    if (monthPast)
                    {
                        year++;
                    }
                    break;

                case "x":     // next
                    if (!monthFuture)
                    {
                        year++;
                    }
                    break;
                }

                yearFixed = true;
            }

            // create date
            var date = new AbstractPeriod
            {
                Date = new DateTime(year, month, 1)
            };

            // fix month and maybe year
            date.Fix(FixPeriod.Month);
            if (yearFixed)
            {
                date.Fix(FixPeriod.Year);
            }

            // remove and insert
            data.ReplaceTokensByDates(match.Index, match.Length, date);

            return(true);
        }
示例#11
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            // determine if it is time
            if (
                match.Groups[5].Success || // во фразе есть число
                match.Groups[6].Success || // во фразе есть "часов"
                match.Groups[4].Success || // во фразе есть "час"
                match.Groups[1].Success || // во начале есть "утра/дня/вечера/ночи"
                match.Groups[9].Success    // то же самое в конце
                )
            {
                if (!match.Groups[5].Success)
                {
                    // no number in phrase
                    var partOfDay = match.Groups[9].Success
                        ? match.Groups[9].Value
                        : match.Groups[1].Success
                            ? match.Groups[1].Value
                            : "";

                    // no part of day AND no "from" token in phrase, quit
                    if (partOfDay != "d" && partOfDay != "g" && !match.Groups[2].Success)
                    {
                        return(false);
                    }
                }

                // hours and minutes
                var hours = match.Groups[5].Success ? int.Parse(data.Tokens[match.Groups[5].Index].Value) : 1;
                if (hours >= 0 && hours <= 23)
                {
                    // try minutes
                    var minutes = 0;
                    if (match.Groups[8].Success)
                    {
                        var m = int.Parse(data.Tokens[match.Groups[8].Index].Value);
                        if (m >= 0 && m <= 59)
                        {
                            minutes = m;
                        }
                    }
                    else if (match.Groups[3].Success && hours > 0)
                    {
                        switch (match.Groups[3].Value)
                        {
                        case "Q":     // quarter
                            hours--;
                            minutes = 15;
                            break;

                        case "H":     // half
                            hours--;
                            minutes = 30;
                            break;
                        }
                    }

                    // create time
                    var date = new AbstractPeriod();
                    date.Fix(FixPeriod.TimeUncertain);
                    if (hours > 12)
                    {
                        date.Fix(FixPeriod.Time);
                    }

                    // correct time
                    if (hours <= 12)
                    {
                        var part = "d"; // default
                        if (match.Groups[9].Success || match.Groups[1].Success)
                        {
                            // part of day
                            part = match.Groups[1].Success ? match.Groups[1].Value : match.Groups[9].Value;
                            date.Fix(FixPeriod.Time);
                        }
                        else
                        {
                            date.Fix(FixPeriod.TimeUncertain);
                        }

                        switch (part)
                        {
                        case "d":     // day
                            if (hours <= 4)
                            {
                                hours += 12;
                            }
                            break;

                        case "v":     // evening
                            if (hours <= 11)
                            {
                                hours += 12;
                            }
                            break;

                        case "g":     // night
                            hours += 12;
                            break;
                        }

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

                    date.Time = new TimeSpan(hours, minutes, 0);

                    // remove and insert
                    var toTime = data.Tokens[match.Index];
                    data.ReplaceTokensByDates(match.Index, match.Length, date);

                    if (match.Groups[2].Success && match.Groups[2].Value == "t")
                    {
                        // return "to" to correct period parsing
                        data.ReturnTokens(match.Index, "t", toTime);
                    }

                    return(true);
                }
            }

            return(false);
        }
示例#12
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            var dates      = new List <AbstractPeriod>();
            var monthFixed = false;

            // parse month
            var mStr  = data.Tokens[match.Index + match.Groups[1].Length].Value;
            var month = ParserUtils.FindIndex(mStr, Keywords.Months()) + 1;

            if (month == 0)
            {
                month = userDate.Month;             // # instead M
            }
            else
            {
                monthFixed = true;
            }

            // create dates
            for (var i = match.Index; i < match.Index + match.Groups[1].Length; i++)
            {
                var t = data.Tokens[i];
                int.TryParse(t.Value, out var day);
                if (day <= 0)
                {
                    continue;           // this is "AND" or other token
                }
                // current token is number, store it as a day
                var period = new AbstractPeriod
                {
                    Date = new DateTime(
                        userDate.Year,
                        month,
                        ParserUtils.GetDayValidForMonth(userDate.Year, month, day)
                        )
                };

                // fix from week to day, and year/month if it was
                period.Fix(FixPeriod.Week, FixPeriod.Day);
                if (monthFixed)
                {
                    period.Fix(FixPeriod.Month);
                }

                // store
                dates.Add(period);

                // compare with last if month not fixed
                if (!monthFixed && dates.Count > 0 && dates.Last().Date < period.Date)
                {
                    period.Date = new DateTime(
                        userDate.Year,
                        month + 1,
                        ParserUtils.GetDayValidForMonth(userDate.Year, month + 1, day)
                        );
                }
            }

            // replace all scanned tokens
            data.ReplaceTokensByDates(match.Index, match.Length, dates.ToArray());

            return(true);
        }
示例#13
0
        protected override bool ParseMatch(DatesRawData data, Match match, DateTime userDate)
        {
            if (match.Groups[1].Success ^ match.Groups[4].Success)
            {
                // if "after" of "before", but not both and not neither
                var letters    = match.Groups[2].Value.Select(s => s.ToString()).ToList();
                var lastNumber = 1;
                var tokenIndex = match.Groups[2].Index;
                var direction  = 1; // moving to the future
                if (match.Groups[4].Success && match.Groups[4].Value == "b")
                {
                    direction = -1; // "before"
                }

                var date = new AbstractPeriod
                {
                    SpanDirection = direction,
                };

                // save current day to offser object
                var offset = new DateTimeOffset(userDate);

                letters.ForEach(l =>
                {
                    switch (l)
                    {
                    case "N":     // "and", skip it
                        break;

                    case "0":     // number, store it
                        int.TryParse(data.Tokens[tokenIndex].Value, out lastNumber);
                        break;

                    case "Y":     // year(s)
                        offset = offset.AddYears(direction * lastNumber);
                        date.FixDownTo(FixPeriod.Month);
                        lastNumber = 1;
                        break;

                    case "m":     // month(s)
                        offset = offset.AddMonths(direction * lastNumber);
                        date.FixDownTo(FixPeriod.Week);
                        lastNumber = 1;
                        break;

                    case "w":     // week(s)
                        offset = offset.AddDays(7 * direction * lastNumber);
                        date.FixDownTo(FixPeriod.Day);
                        lastNumber = 1;
                        break;

                    case "d":     // day(s)
                        offset = offset.AddDays(direction * lastNumber);
                        date.FixDownTo(FixPeriod.Day);
                        lastNumber = 1;
                        break;

                    case "h":     // hour(s)
                        offset = offset.AddHours(direction * lastNumber);
                        date.FixDownTo(FixPeriod.Time);
                        lastNumber = 1;
                        break;

                    case "e":     // minute(s)
                        offset = offset.AddMinutes(direction * lastNumber);
                        date.FixDownTo(FixPeriod.Time);
                        break;
                    }

                    tokenIndex++;
                });

                // set date
                date.Date = new DateTime(offset.DateTime.Year, offset.DateTime.Month, offset.DateTime.Day);
                if (date.IsFixed(FixPeriod.Time))
                {
                    date.Time = new TimeSpan(offset.DateTime.Hour, offset.DateTime.Minute, 0);
                }
                date.Span = offset - userDate;

                // remove and insert
                data.ReplaceTokensByDates(match.Index, match.Length, date);

                return(true);
            }

            return(false);
        }