private OffsetDateTime CreateUpdatedOffsetDateTimeFromTokens(OffsetDateTime existingOffsetDateTime, DateToken dateToken, TimeToken timeToken) { var existingLocalDateTime = existingOffsetDateTime.LocalDateTime; var day = existingLocalDateTime.Day; var month = existingLocalDateTime.Month; var year = existingLocalDateTime.Year; if (dateToken != null) { if (dateToken.Day.HasValue) day = dateToken.Day.Value; if (dateToken.Month.HasValue) month = dateToken.Month.Value; if (dateToken.Year.HasValue) year = dateToken.Year.Value; } var hour = 12; var minute = 0; if (timeToken != null) { hour = timeToken.Hour; if (timeToken.Meridiem == Meridiem.AM && hour == 12) hour = 0; if (timeToken.Meridiem == Meridiem.PM && hour < 12) hour += 12; minute = timeToken.Minute ?? 0; } try { return new LocalDateTime(year, month, day, hour, minute).WithOffset(existingOffsetDateTime.Offset); } catch (ArgumentOutOfRangeException) { throw new InvalidTokenValueException(ErrorMessages.InvalidDateTime); } }
private Answer GetAnswerToTimeConversionQuestion(Question question, DateToken knownDateToken, TimeToken knownTimeToken, CityOrTimezoneToken knownCityOrTimezone, CityOrTimezoneToken unknownCityOrTimezone) { var knownEntityOffsetDateTime = CreateUpdatedOffsetDateTimeFromTokens(knownCityOrTimezone.GetCurrentTimeAsOffsetDateTime(), knownDateToken, knownTimeToken); Instant knownCityOrTimezoneInstant; String note = null; if (knownCityOrTimezone.GetType() == typeof(CityToken)) { var cityToken = (CityToken)knownCityOrTimezone; ZoneLocalMapping knownCityOrTimezoneZoneLocalMapping = DateTimeZoneProviders.Tzdb[cityToken.City.Timezone].MapLocal(knownEntityOffsetDateTime.LocalDateTime); if (knownCityOrTimezoneZoneLocalMapping.Count == 1) { knownCityOrTimezoneInstant = knownCityOrTimezoneZoneLocalMapping.Single().ToInstant(); } else if (knownCityOrTimezoneZoneLocalMapping.Count > 1) { knownCityOrTimezoneInstant = knownCityOrTimezoneZoneLocalMapping.First().ToInstant(); note = String.Format("In {0} the time {1} occurs twice due to daylight saving time changes when clocks are put back, we are using the first occurance of that time.", cityToken.City.FormattedName, knownEntityOffsetDateTime.LocalDateTime.GetFormattedTimeAndDate()); } else { knownCityOrTimezoneInstant = knownCityOrTimezoneZoneLocalMapping.LateInterval.Start.WithOffset(knownCityOrTimezoneZoneLocalMapping.LateInterval.WallOffset).ToInstant(); note = String.Format("In {0} the time {1} does not occur due to daylight saving time changes when clocks are put forward, we are using the next valid time.", cityToken.City.FormattedName, knownEntityOffsetDateTime.LocalDateTime.GetFormattedTimeAndDate()); } } else if (knownCityOrTimezone.GetType() == typeof(TimezoneToken)) { var timezoneToken = (TimezoneToken)knownCityOrTimezone; knownCityOrTimezoneInstant = knownEntityOffsetDateTime.LocalDateTime.WithOffset(timezoneToken.Timezone.Offset).ToInstant(); } else { throw new NotImplementedException(); } var answerText = String.Format("It is {0} in {1} when it is {2} in {3}", unknownCityOrTimezone.GetLocalDateTime(knownCityOrTimezoneInstant).GetFormattedTimeAndDate(), unknownCityOrTimezone.GetFormattedNameAndTimezone(knownCityOrTimezoneInstant), knownEntityOffsetDateTime.LocalDateTime.GetFormattedTimeAndDate(), knownCityOrTimezone.GetFormattedNameAndTimezone(knownEntityOffsetDateTime.ToInstant())); var answer = new Answer(question, true, true, answerText); answer.Note = note; return answer; }
private IList<Token> GetDayMonthYearFormattedDates(Question question) { var tokens = new List<Token>(); var monthNamesRegex = "(jan(uary)?|febr(uary)?|mar(ch)?|apr(il)?|may|jun(e)?|jul(y)?|aug(ust)?|sep(tember)?|oct(ober)?|nov(ember)?|dec(ember)?)"; var matches = Regex.Matches(question.QuestionText, @"(?<day>\d{1,2})(th|st|nd|rd)?(\sof|/|-)?\s?(?<month_name>" + monthNamesRegex + @")((/|-|\s)(?<year>\d{2,4}))?", RegexOptions.IgnoreCase); foreach (Match match in matches) { Group group = match.Groups[0]; var monthNameMatch = match.Groups["month_name"]; var dayMatch = match.Groups["day"]; var yearMatch = match.Groups["year"]; var month = GetMonth(monthNameMatch.Value); var day = int.Parse(dayMatch.Value); int? year = null; if(!string.IsNullOrEmpty(yearMatch.Value)) year = int.Parse(yearMatch.Value); year = MakeYearInThisCenturyIfOnly2Digits(year); var tokenResult = new DateToken(group.Value, group.Index, day, month, year); tokens.Add(tokenResult); } return tokens; }
private IList<Token> GetMonthDayYearFormattedDates(Question question) { var tokens = new List<Token>(); var monthNamesRegex = "(jan(uary)?|feb(ruary)?|mar(ch)?|apr(il)?|may|jun(e)?|jul(y)?|aug(ust)?|sep(tember)?|oct(ober)?|nov(ember)?|dec(ember)?)"; var matches = Regex.Matches(question.QuestionText, @"(?<month_name>" + monthNamesRegex + @")(\sthe\s|,\s|,|\s)(?<first_number>\d{1,4})(th|st|nd|rd)?(?<second_number>\s?\d{4})?", RegexOptions.IgnoreCase); foreach (Match match in matches) { Group group = match.Groups[0]; var monthNameMatch = match.Groups["month_name"]; var firstNumberMatch = match.Groups["first_number"]; var secondNumberMatch = match.Groups["second_number"]; var month = GetMonth(monthNameMatch.Value); int? firstNumber = int.Parse (firstNumberMatch.Value); int? secondNumber = null; if(!string.IsNullOrEmpty (secondNumberMatch.Value)) secondNumber = int.Parse(secondNumberMatch.Value); int? day = null; int? year = null; if(secondNumber.HasValue) { day = firstNumber; year = secondNumber; } else { if(firstNumber <= 31){ day = firstNumber; } else{ year = firstNumber; } } year = MakeYearInThisCenturyIfOnly2Digits(year); var tokenResult = new DateToken(group.Value, monthNameMatch.Index, day, month, year); tokens.Add(tokenResult); } return tokens; }
private IList<Token> GetHyphenAndSlashFormattedDates(Question question) { var tokens = new List<Token>(); var matches = Regex.Matches(question.QuestionText, @"(?<first_number>\d{1,2})(-|/)(?<second_number>\d{1,2})(-|/)(?<year>\d{2,4})", RegexOptions.IgnoreCase); foreach (Match match in matches) { Group group = match.Groups[0]; var yearMatch = match.Groups["year"]; var firstNumberMatch = match.Groups["first_number"]; var secondNumberMatch = match.Groups["second_number"]; int? year = int.Parse(yearMatch.Value); var firstNumber = int.Parse(firstNumberMatch.Value); var secondNumber = int.Parse(secondNumberMatch.Value); int day = secondNumber; int month = firstNumber; if(firstNumber > 12 && secondNumber <= 12){ day = firstNumber; month = secondNumber; } year = MakeYearInThisCenturyIfOnly2Digits(year); var tokenResult = new DateToken(group.Value, yearMatch.Index, day, month, year); tokens.Add(tokenResult); } return tokens; }
private IList<Token> GetYearOnlyDates(Question question) { var tokens = new List<Token>(); var matches = Regex.Matches(question.QuestionText, @"\s(?<year>\d{4})(\s|$)", RegexOptions.IgnoreCase); foreach (Match match in matches) { Group yearMatch = match.Groups["year"]; var year = int.Parse (yearMatch.Value); var tokenResult = new DateToken(yearMatch.Value, yearMatch.Index, null, null, year); tokens.Add(tokenResult); } return tokens; }