internal static ExtendedDateTimePossibilityCollection ToPossibilityCollection(UnspecifiedExtendedDateTime unspecifiedExtendedDateTime) { var extendedDateTimePossibilityCollection = new ExtendedDateTimePossibilityCollection(); var extendedDateTimeRange = new ExtendedDateTimeRange(); var startExtendedDateTime = new ExtendedDateTime(); var endExtendedDateTime = new ExtendedDateTime(); extendedDateTimeRange.Start = startExtendedDateTime; extendedDateTimeRange.End = endExtendedDateTime; extendedDateTimePossibilityCollection.Add(extendedDateTimeRange); if (unspecifiedExtendedDateTime.Year.Length != 4) // Year { throw new ConversionException("An UnspecifiedExtendedDateTime year must be four characters long."); } var yearStartBuffer = new List <char>(); var yearEndBuffer = new List <char>(); for (int i = 0; i < 4; i++) { if (unspecifiedExtendedDateTime.Year[0] == 'u') { if (i == 0) { yearStartBuffer.Add('-'); } yearStartBuffer.Add('9'); yearEndBuffer.Add('9'); } else if (unspecifiedExtendedDateTime.Year[i] == 'u') { yearStartBuffer.Add('0'); yearEndBuffer.Add('9'); } else { yearStartBuffer.Add(unspecifiedExtendedDateTime.Year[i]); yearEndBuffer.Add(unspecifiedExtendedDateTime.Year[i]); } } var yearStart = int.Parse(new string(yearStartBuffer.ToArray())); var yearEnd = int.Parse(new string(yearEndBuffer.ToArray())); if (unspecifiedExtendedDateTime.Month == null) // Month { startExtendedDateTime.Year = yearStart; endExtendedDateTime.Year = yearEnd; return(extendedDateTimePossibilityCollection); } if (unspecifiedExtendedDateTime.Month.Length != 2) { throw new ConversionException("A month must be two characters long."); } var monthStartBuffer = new List <char>(); var monthEndBuffer = new List <char>(); var isFirstMonthDigitUnspecified = false; if (unspecifiedExtendedDateTime.Month[0] == 'u') { monthStartBuffer.Add('0'); monthEndBuffer.Add('1'); isFirstMonthDigitUnspecified = true; } else { monthStartBuffer.Add(unspecifiedExtendedDateTime.Month[0]); monthEndBuffer.Add(unspecifiedExtendedDateTime.Month[0]); } if (unspecifiedExtendedDateTime.Month[1] == 'u') { if (isFirstMonthDigitUnspecified) { monthStartBuffer.Add('1'); monthEndBuffer.Add('2'); } else { var firstDigit = int.Parse(unspecifiedExtendedDateTime.Month[0].ToString()); if (firstDigit == 0) { monthStartBuffer.Add('1'); monthEndBuffer.Add('9'); } else if (firstDigit == 1) { monthStartBuffer.Add('0'); monthEndBuffer.Add('2'); } else { throw new ConversionException("A month must be between 1 and 12."); } } } else { if (isFirstMonthDigitUnspecified) { var secondDigit = int.Parse(unspecifiedExtendedDateTime.Month[1].ToString()); if (secondDigit > 2) // Month must be in the range of 01 to 09 { monthEndBuffer[0] = '0'; } } monthStartBuffer.Add(unspecifiedExtendedDateTime.Month[1]); monthEndBuffer.Add(unspecifiedExtendedDateTime.Month[1]); } var monthStart = int.Parse(new string(monthStartBuffer.ToArray())); var monthEnd = int.Parse(new string(monthEndBuffer.ToArray())); if (unspecifiedExtendedDateTime.Day == null) // Day { startExtendedDateTime.Year = yearStart; startExtendedDateTime.Month = monthStart; endExtendedDateTime.Year = yearEnd; endExtendedDateTime.Month = monthEnd; return(extendedDateTimePossibilityCollection); } if (unspecifiedExtendedDateTime.Day.Length != 2) { throw new ConversionException("A day must be two characters long."); } var dayStartBuffer = new List <char>(); var dayEndBuffer = new List <char>(); var daysInEndMonth = ExtendedDateTimeCalculator.DaysInMonth(yearEnd, monthEnd); var isFirstDayDigitUnspecified = false; if (unspecifiedExtendedDateTime.Day[0] == 'u') { dayStartBuffer.Add('0'); dayEndBuffer.Add(daysInEndMonth.ToString()[0]); isFirstDayDigitUnspecified = true; } else { dayStartBuffer.Add(unspecifiedExtendedDateTime.Day[0]); dayEndBuffer.Add(unspecifiedExtendedDateTime.Day[0]); } if (unspecifiedExtendedDateTime.Day[1] == 'u') { if (isFirstDayDigitUnspecified) { dayStartBuffer.Add('1'); dayEndBuffer.Add(daysInEndMonth.ToString()[1]); } else { var firstDigit = int.Parse(unspecifiedExtendedDateTime.Day[0].ToString()); if (firstDigit == 0) // Day is 01 to 09 { dayStartBuffer.Add('1'); dayEndBuffer.Add('9'); } else if (firstDigit == 1) // Day is 10 to 19 { dayStartBuffer.Add('0'); dayEndBuffer.Add('9'); } else if (firstDigit == 2) // Day is 20 to 28 (if end month is February in a non-leap year) or 29 { dayStartBuffer.Add('0'); if (daysInEndMonth == 28) { dayEndBuffer.Add('8'); } else { dayEndBuffer.Add('9'); } } else if (firstDigit == 3) // Day is 30 to 30 or 31 (depending on end month) { dayStartBuffer.Add('0'); if (daysInEndMonth == 30) { dayEndBuffer.Add('0'); } else { dayEndBuffer.Add('1'); } } else { throw new ConversionException("A day must be between 1 and either 28, 29, 30, or 31 depending on the month."); } } } else { if (isFirstDayDigitUnspecified) { var secondDigit = int.Parse(unspecifiedExtendedDateTime.Day[1].ToString()); if (secondDigit > daysInEndMonth.ToString()[1]) // Decrement the first digit of the end day. { dayEndBuffer[0] = (int.Parse(dayEndBuffer[0].ToString()) - 1).ToString()[0]; } } dayStartBuffer.Add(unspecifiedExtendedDateTime.Day[1]); dayEndBuffer.Add(unspecifiedExtendedDateTime.Day[1]); } var dayStart = int.Parse(new string(dayStartBuffer.ToArray())); var dayEnd = int.Parse(new string(dayEndBuffer.ToArray())); var rangeBuffer = new List <ExtendedDateTime>(); // Collects consecutive dates, which are then converted into an ExtendedDateTimeRange. extendedDateTimePossibilityCollection.Clear(); for (var year = yearStart; year <= yearEnd; year++) { for (var month = monthStart; month <= monthEnd; month++) { for (var day = dayStart; day <= dayEnd; day++) { if (day > ExtendedDateTimeCalculator.DaysInMonth(year, month)) { if (rangeBuffer.Count == 1) { extendedDateTimePossibilityCollection.Add(new ExtendedDateTime(year, month, day)); rangeBuffer.Clear(); } else if (rangeBuffer.Count > 0) { extendedDateTimePossibilityCollection.Add(new ExtendedDateTimeRange(rangeBuffer.First(), rangeBuffer.Last())); rangeBuffer.Clear(); } } else { rangeBuffer.Add(new ExtendedDateTime(year, month, day)); } if (day == dayEnd) { if (rangeBuffer.Count == 1) { extendedDateTimePossibilityCollection.Add(new ExtendedDateTime(year, month, day)); rangeBuffer.Clear(); } else if (rangeBuffer.Count > 0) { extendedDateTimePossibilityCollection.Add(new ExtendedDateTimeRange(rangeBuffer.First(), rangeBuffer.Last())); rangeBuffer.Clear(); } } } } } return(extendedDateTimePossibilityCollection); }
internal static UnspecifiedExtendedDateTime Parse(string unspecifiedExtendedDateTimeString, UnspecifiedExtendedDateTime unspecifiedExtendedDateTime = null) { if (unspecifiedExtendedDateTimeString.Length > 10) { throw new ParseException("An unspecified extended date time must be between 4 and 10 characters long.", unspecifiedExtendedDateTimeString); } var components = unspecifiedExtendedDateTimeString.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries); if (components.Length > 3) { throw new ParseException("An unspecified extended date time can have at most two components.", unspecifiedExtendedDateTimeString); } if (unspecifiedExtendedDateTime == null) { unspecifiedExtendedDateTime = new UnspecifiedExtendedDateTime(); } unspecifiedExtendedDateTime.Year = components[0]; if (components.Length == 1) { return(unspecifiedExtendedDateTime); } unspecifiedExtendedDateTime.Month = components[1]; if (components.Length == 2) { return(unspecifiedExtendedDateTime); } unspecifiedExtendedDateTime.Day = components[2]; return(unspecifiedExtendedDateTime); }