Example #1
0
 internal TokenDate(int position, DateTime date, Specificity isSpecific)
     : base(position)
 {
     this.date = date;
     this.isSpecific = isSpecific;
     Logger.Info("Created a date token object", "TokenDate::TokenDate");
 }
        //@jenna A0083536B
        /// <summary>
        /// This method searches an input list of strings for all valid dates and generates a list of date tokens
        /// corresponding to all the found matched date strings using regexes.
        /// </summary>
        /// <param name="input">The list of command phrases, separated words and/or time/date phrases</param>
        /// <returns>List of date tokens</returns>
        public List<TokenDate> GenerateDateTokens(List<string> input)
        {
            int day = 0;
            int month = 0;
            int year = 0;
            int index = 0;
            List<TokenDate> dateTokens = new List<TokenDate>();

            foreach (string word in input)
            {
                Specificity isSpecific = new Specificity();
                DateTime dateTime = new DateTime();
                TokenDate dateToken = null;
                string wordLower = word.ToLower();
                if (CustomDictionary.IsValidDate(wordLower)
                    || CustomDictionary.IsToday(wordLower)
                    || CustomDictionary.IsTomorrow(wordLower)
                    || CustomDictionary.IsValidMonthWord(wordLower)
                    )
                {
                    string dayString = String.Empty;
                    string monthString = String.Empty;
                    string yearString = String.Empty;
                    if (CustomDictionary.IsToday(wordLower))
                    {
                        day = DateTime.Now.Day;
                        month = DateTime.Now.Month;
                        year = DateTime.Now.Year;
                    }
                    else if (CustomDictionary.IsTomorrow(wordLower))
                    {
                        day = DateTime.Now.Day + 1;
                        month = DateTime.Now.Month;
                        year = DateTime.Now.Year;
                    }
                    else if (CustomDictionary.IsValidMonthWord(wordLower))
                    {
                        monthString = CustomDictionary.date_alphabeticMonth.Match(wordLower).Groups["month"].Value;
                        isSpecific.Day = false;
                        isSpecific.Year = false;
                        day = 1;
                        month = ConvertToNumericMonth(monthString);
                        year = DateTime.Now.Year;
                    }
                    else
                    {
                        Match match = GetDateMatch(wordLower);
                        GetMatchTagValues(match, ref dayString, ref monthString, ref yearString);
                        ConvertDateStringsToInt(dayString, monthString, yearString, ref day, ref month, ref year);
                    }
                    // no day input
                    if (day == 0)
                    {
                        isSpecific.Day = false;
                        day = 1;
                    }
                    // no month input
                    if (month == 0)
                    {
                        isSpecific.Month = false;
                        month = DateTime.Today.Month;
                    }
                    // no year input
                    if (year == 0 || isSpecific.Year == false)
                    {
                        isSpecific.Year = false;
                        year = DateTime.Today.Year;
                        dateTime = TryParsingDate(year, month, day, true);
                        if (DateTime.Compare(dateTime, DateTime.Today) < 0)
                        {
                            if (isSpecific.Month == false)
                            {
                                month = DateTime.Today.AddMonths(1).Month;
                                year = DateTime.Today.AddMonths(1).Year;
                            }
                            else if (month != DateTime.Now.Month)
                            {
                                year = DateTime.Today.AddYears(1).Year;
                            }
                        }
                    }
                    // if year has less than 4 digit input.
                    else if (year < 1000)
                    {
                        year += 2000;
                    }
                    dateTime = TryParsingDate(year, month, day, false);
                    Logger.Info("Date word found: " + dateTime, "GenerateDateTokens::TokenGenerator");
                    dateToken = new TokenDate(index, dateTime, isSpecific);
                    dateTokens.Add(dateToken);
                }
                index++;
            }
            return dateTokens;
        }
        /// <summary>
        /// Ensures a given unspecific date is beyond a specified limit. Moves it to the first appropriate date if not.
        /// </summary>
        /// <param name="dateToCheck">The given date to check.</param>
        /// <param name="dateSpecificity">The given date's specificity</param>
        /// <param name="limit">The limit to check the given date against.</param>
        /// <param name="allowCurrent">Flag to indicate if the date should be unchanged or not if it falls within a range close to the limit
        /// and cannot be determined accurately due to its specificity.</param>
        /// <returns></returns>
        private void PushDateToBeyondLimit(ref DateTime? dateToCheck, ref Specificity dateSpecificity, DateTime limit, bool allowCurrent)
        {
            if (this.commandType == CommandType.ADD)
            {
                if (IsDayOfWeekSet(allowCurrent))
                {
                    while (limit > dateToCheck)
                    {
                        dateToCheck = dateToCheck.Value.AddDays(7);
                    }
                }

                if (DateIsAmbiguous(ref dateToCheck, ref dateSpecificity) &&
                    allowCurrent)
                    return;

                // Move by days until day is beyond limits.
                if (!dateSpecificity.Day && !dateSpecificity.Month)
                {
                    while (limit > dateToCheck)
                        dateToCheck = dateToCheck.Value.AddDays(1);

                    dateSpecificity.Day = true;
                }

                // Move by months until date is beyond limits
                else if (!dateSpecificity.Month)
                {
                    while (limit > dateToCheck)
                        dateToCheck = dateToCheck.Value.AddMonths(1);

                    dateSpecificity.Month = true;
                }
                // Move by years until date is beyond limits
                else if (!dateSpecificity.Year)
                {
                    if (dateToCheck.Value.Date == DateTime.Today.Date && allowCurrent)
                        return;

                    while (limit > dateToCheck)
                        dateToCheck = dateToCheck.Value.AddYears(1);

                    dateSpecificity.Year = true;
                }
            }
        }
 /// <summary>
 /// Returns if a date is ambiguous enough to fit today's date.
 /// </summary>
 /// <param name="dateToCheck">The date to check.</param>
 /// <param name="dateSpecificity">The specificity of the date.</param>
 /// <returns></returns>
 private bool DateIsAmbiguous( ref DateTime? dateToCheck, ref Specificity dateSpecificity )
 {
     return dateToCheck.Value.Month == DateTime.Today.Month &&
            dateToCheck.Value.Year == DateTime.Today.Year &&
            dateSpecificity.Day == false;
 }
        /// <summary>
        /// Combines the time and date fields into a single DateTime that is after the specified limit.
        /// </summary>
        /// <param name="time">The time to merge.</param>
        /// <param name="date">The date to merge.</param>
        /// <param name="dateSpecificity">The specificity of the date.</param>
        /// <param name="limit">The limit to ensure the combined date/time is after.</param>
        /// <param name="allowCurrent">Flag indicating whether to allow ambiguous dates matching today to pass the limit check.</param>
        /// <returns></returns>
        private DateTime? CombineDateAndTime(TimeSpan? time, DateTime? date, Specificity dateSpecificity, DateTime limit, bool allowCurrent)
        {
            DateTime? combinedDT = null;
            // Time defined but not date
            if (date == null && time != null)
            {
                TimeSpan limitTime = limit.TimeOfDay;
                TimeSpan taskTime = time.Value;
                combinedDT = new DateTime(limit.Year, limit.Month, limit.Day, taskTime.Hours, taskTime.Minutes, taskTime.Seconds);
            }
            // Date and Time both defined
            else if (date != null && time != null)
            {
                DateTime setDate = date.Value;
                TimeSpan setTime = time.Value;
                combinedDT = new DateTime(setDate.Year, setDate.Month, setDate.Day, setTime.Hours, setTime.Minutes, setTime.Seconds);
            }
            // Date defined but not time
            else if (time == null && date != null)
            {
                combinedDT = date;
            }

            if (limit > combinedDT)
                PushDateToBeyondLimit(ref combinedDT, ref dateSpecificity, limit, allowCurrent && time == null);

            return combinedDT;
        }
 /// <summary>
 /// Sets the configured end date to the specified date and specificity.
 /// Moves the end date to the start date if necessary.
 /// </summary>
 /// <param name="Value">The end daate to be set.</param>
 /// <param name="IsSpecific">The specificity of the end date.</param>
 /// <returns></returns>
 internal void SetConditionalEndDate(DateTime Value, Specificity IsSpecific)
 {
     if (startDateOnly == null && endDateOnly != null)
     {
         this.startDateOnly = this.endDateOnly;
         this.isSpecific.StartDate = this.isSpecific.EndDate;
     }
     this.endDateOnly = Value;
     this.isSpecific.EndDate = IsSpecific;
 }