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; }