public FixedCutoff DeepCloneWithUnitOfTime(UnitOfTime unitOfTime) { var result = new FixedCutoff( unitOfTime); return(result); }
public ReportingPeriod DeepCloneWithEnd(UnitOfTime end) { var result = new ReportingPeriod( this.Start?.DeepClone(), end); return(result); }
public ReportingPeriod DeepCloneWithStart(UnitOfTime start) { var result = new ReportingPeriod( start, this.End?.DeepClone()); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="FixedCutoff"/> class. /// </summary> /// <param name="unitOfTime">The unit-of-time that is the cutoff.</param> public FixedCutoff( UnitOfTime unitOfTime) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } this.UnitOfTime = unitOfTime; }
/// <summary> /// Creates a reporting period from a unit-of-time. /// </summary> /// <param name="unitOfTime">The unit-of-time to use in the reporting period.</param> /// <returns> /// A reporting period where the Start and End components are equal to the specified unit-of-time. /// </returns> public static ReportingPeriod ToReportingPeriod( this UnitOfTime unitOfTime) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } var result = new ReportingPeriod(unitOfTime, unitOfTime); return(result); }
/// <summary> /// Adds the specified number of units to a unit-of-time. /// </summary> /// <param name="unitOfTime">The unit-of-time to add to.</param> /// <param name="unitsToAdd">The number of units to add (use negative numbers to subtract units).</param> /// <returns> /// The result of adding the specified number of units to the specified units-of-time. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="unitOfTime"/> is null.</exception> /// <exception cref="InvalidOperationException"><paramref name="unitOfTime"/> is unbounded.</exception> public static UnitOfTime Plus( this UnitOfTime unitOfTime, int unitsToAdd) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } switch (unitOfTime) { case CalendarDay unitOfTimeAsCalendarDay: return(unitOfTimeAsCalendarDay.Plus(unitsToAdd)); case CalendarMonth unitOfTimeAsCalendarMonth: return(unitOfTimeAsCalendarMonth.Plus(unitsToAdd)); case CalendarQuarter unitOfTimeAsCalendarQuarter: return(unitOfTimeAsCalendarQuarter.Plus(unitsToAdd)); case CalendarYear unitOfTimeAsCalendarYear: return(unitOfTimeAsCalendarYear.Plus(unitsToAdd)); case CalendarUnbounded _: throw new InvalidOperationException("Cannot add to unbounded time."); case FiscalMonth unitOfTimeAsFiscalMonth: return(unitOfTimeAsFiscalMonth.Plus(unitsToAdd)); case FiscalQuarter unitOfTimeAsFiscalQuarter: return(unitOfTimeAsFiscalQuarter.Plus(unitsToAdd)); case FiscalYear unitOfTimeAsFiscalYear: return(unitOfTimeAsFiscalYear.Plus(unitsToAdd)); case FiscalUnbounded _: throw new InvalidOperationException("Cannot add to unbounded time."); case GenericMonth unitOfTimeAsGenericMonth: return(unitOfTimeAsGenericMonth.Plus(unitsToAdd)); case GenericQuarter unitOfTimeAsGenericQuarter: return(unitOfTimeAsGenericQuarter.Plus(unitsToAdd)); case GenericYear unitOfTimeAsGenericYear: return(unitOfTimeAsGenericYear.Plus(unitsToAdd)); case GenericUnbounded _: throw new InvalidOperationException("Cannot add to unbounded time."); } throw new NotSupportedException("this type of unit-of-time is not supported: " + unitOfTime.GetType()); }
/// <inheritdoc /> public override RelativeSortOrder CompareToForRelativeSortOrder(UnitOfTime other) { if (ReferenceEquals(other, null)) { return(RelativeSortOrder.ThisInstanceFollowsTheOtherInstance); } if (!(other is CalendarMonth otherAsCalendarMonth)) { throw new ArgumentException(Invariant($"Attempting to compare objects of different types. This object is of type 'CalendarMonth' whereas the other object is of type '{other.GetType().ToStringReadable()}'.")); } var result = this.CompareToForRelativeSortOrder(otherAsCalendarMonth); return(result); }
/// <summary> /// Determines if a unit-of-time is contained within a reporting period. /// For example, 2Q2017 is contained within a reporting period of 1Q2017-4Q2017. /// </summary> /// <remarks> /// If the unit-of-time is equal to one of the endpoints of the reporting period, /// that unit-of-time is considered to be within the reporting period. /// </remarks> /// <param name="reportingPeriod">The reporting period.</param> /// <param name="unitOfTime">The unit-of-time to check against a reporting period.</param> /// <returns> /// true if the unit-of-time is contained within the reporting period; false otherwise. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="unitOfTime"/> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="reportingPeriod"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="unitOfTime"/> cannot be compared against <paramref name="reportingPeriod"/> because they represent different <see cref="UnitOfTime.UnitOfTimeKind"/>.</exception> public static bool Contains( this ReportingPeriod reportingPeriod, UnitOfTime unitOfTime) { if (reportingPeriod == null) { throw new ArgumentNullException(nameof(reportingPeriod)); } if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } if (unitOfTime.UnitOfTimeKind != reportingPeriod.GetUnitOfTimeKind()) { throw new ArgumentException(Invariant($"{nameof(unitOfTime)} cannot be compared against {nameof(reportingPeriod)} because they represent different {nameof(UnitOfTimeKind)}.")); } var result = reportingPeriod.Contains(new ReportingPeriod(unitOfTime, unitOfTime)); return(result); }
/// <summary> /// Initializes a new instance of the <see cref="ReportingPeriod"/> class. /// </summary> /// <param name="start">The start of the reporting period.</param> /// <param name="end">The end of the reporting period.</param> /// <exception cref="ArgumentNullException"><paramref name="start"/> or <paramref name="end"/> are null.</exception> /// <exception cref="ArgumentException"><paramref name="start"/> and <paramref name="end"/> are bounded and are different concrete types of units-of-time.</exception> /// <exception cref="ArgumentException"><paramref name="start"/> and/or <paramref name="end"/> is unbounded and are different kinds of units-of-time.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="start"/> is greater than <paramref name="end"/>.</exception> public ReportingPeriod( UnitOfTime start, UnitOfTime end) { if (start == null) { throw new ArgumentNullException(nameof(start)); } if (end == null) { throw new ArgumentNullException(nameof(end)); } if ((start is IAmUnboundedTime) || (end is IAmUnboundedTime)) { if (start.UnitOfTimeKind != end.UnitOfTimeKind) { throw new ArgumentException(Invariant($"{nameof(start)} and/or {nameof(end)} is unbounded and are different kinds of units-of-time.")); } } else { if (start.GetType() != end.GetType()) { throw new ArgumentException(Invariant($"{nameof(start)} and {nameof(end)} are bounded and are different concrete types of units-of-time.")); } if (start > end) { throw new ArgumentOutOfRangeException(nameof(start), Invariant($"{nameof(start)} is greater than {nameof(end)}.")); } } this.Start = start; this.End = end; }
/// <summary> /// Serializes a <see cref="UnitOfTime"/> to a sortable string. /// </summary> /// <param name="unitOfTime">The unit-of-time to serialize.</param> /// <returns> /// Gets a string representation of a unit-of-time that can be deserialized /// into the same unit-of-time and which sorts in the same way that the /// other unit-of-times (of the same type) would sort (earlier time first, later time last). /// </returns> /// <exception cref="ArgumentNullException"><paramref name="unitOfTime"/> is null.</exception> public static string SerializeToSortableString( this UnitOfTime unitOfTime) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } var unitOfTimeType = unitOfTime.GetType(); switch (unitOfTime) { case CalendarDay unitOfTimeAsCalendarDay: { var result = Invariant($"c-{unitOfTimeAsCalendarDay.Year:D4}-{(int)unitOfTimeAsCalendarDay.MonthNumber:D2}-{(int)unitOfTimeAsCalendarDay.DayOfMonth:D2}"); return(result); } case CalendarMonth unitOfTimeAsCalendarMonth: { var result = Invariant($"c-{unitOfTimeAsCalendarMonth.Year:D4}-{(int)unitOfTimeAsCalendarMonth.MonthNumber:D2}"); return(result); } case CalendarQuarter unitOfTimeAsCalendarQuarter: { var result = Invariant($"c-{unitOfTimeAsCalendarQuarter.Year:D4}-Q{(int)unitOfTimeAsCalendarQuarter.QuarterNumber}"); return(result); } case CalendarYear unitOfTimeAsCalendarYear: { var result = Invariant($"c-{unitOfTimeAsCalendarYear.Year:D4}"); return(result); } case CalendarUnbounded _: { var result = "c-unbounded"; return(result); } case FiscalMonth unitOfTimeAsFiscalMonth: { var result = Invariant($"f-{unitOfTimeAsFiscalMonth.Year:D4}-{(int)unitOfTimeAsFiscalMonth.MonthNumber:D2}"); return(result); } case FiscalQuarter unitOfTimeAsFiscalQuarter: { var result = Invariant($"f-{unitOfTimeAsFiscalQuarter.Year:D4}-Q{(int)unitOfTimeAsFiscalQuarter.QuarterNumber}"); return(result); } case FiscalYear unitOfTimeAsFiscalYear: { var result = Invariant($"f-{unitOfTimeAsFiscalYear.Year:D4}"); return(result); } case FiscalUnbounded _: { var result = "f-unbounded"; return(result); } case GenericMonth unitOfTimeAsGenericMonth: { var result = Invariant($"g-{unitOfTimeAsGenericMonth.Year:D4}-{(int)unitOfTimeAsGenericMonth.MonthNumber:D2}"); return(result); } case GenericQuarter unitOfTimeAsGenericQuarter: { var result = Invariant($"g-{unitOfTimeAsGenericQuarter.Year:D4}-Q{(int)unitOfTimeAsGenericQuarter.QuarterNumber}"); return(result); } case GenericYear unitOfTimeAsGenericYear: { var result = Invariant($"g-{unitOfTimeAsGenericYear.Year:D4}"); return(result); } case GenericUnbounded _: { var result = "g-unbounded"; return(result); } default: throw new NotSupportedException("this type of unit-of-time is not supported: " + unitOfTimeType); } }
public static UnitOfTime DeserializeFromSortableString(this string unitOfTime, Type type) { if (!UnitOfTime.IsUnitOfTimeType(type)) { throw new NotSupportedException(Invariant($"Unsupported type {type?.FullName ?? "<NULL TYPE>"}, expected an implmenter {nameof(UnitOfTime)}")); } if (type == null) { throw new ArgumentNullException(nameof(type)); } if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } if (string.IsNullOrWhiteSpace(unitOfTime)) { throw new ArgumentException("unit-of-time string is whitespace", nameof(unitOfTime)); } var serializationFormatMatch = SerializationFormatByType.Select(_ => new { Match = _.Regex.Match(unitOfTime), SerializationFormat = _ }).SingleOrDefault(_ => _.Match.Success); if (serializationFormatMatch == null) { throw new InvalidOperationException("Cannot deserialize string; it is not valid unit-of-time."); } var serializedType = serializationFormatMatch.SerializationFormat.Type; if (!type.IsAssignableFrom(serializedType)) { throw new InvalidOperationException(Invariant($"The unit-of-time appears to be a {serializedType.Name} which cannot be casted to a {type.Name}.")); } string errorMessage = Invariant($"Cannot deserialize string; it appears to be a {serializedType.Name} but it is malformed."); var tokens = serializationFormatMatch.SerializationFormat.Regex.GetGroupNames().Skip(1).Select(_ => serializationFormatMatch.Match.Groups[_].Value).ToArray(); if (serializedType == typeof(CalendarDay)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthOfYear>(tokens[1], errorMessage); var day = ParseEnumOrThrow <DayOfMonth>(tokens[2], errorMessage); try { var deserialized = new CalendarDay(year, month, day); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarMonth)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthOfYear>(tokens[1], errorMessage); try { var deserialized = new CalendarMonth(year, month); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarQuarter)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var quarter = ParseEnumOrThrow <QuarterNumber>(tokens[1], errorMessage); try { var deserialized = new CalendarQuarter(year, quarter); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarYear)) { var year = ParseIntOrThrow(tokens[0], errorMessage); try { var deserialized = new CalendarYear(year); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(CalendarUnbounded)) { var deserialized = new CalendarUnbounded(); return(deserialized); } if (serializedType == typeof(FiscalMonth)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthNumber>(tokens[1], errorMessage); try { var deserialized = new FiscalMonth(year, month); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(FiscalQuarter)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var quarter = ParseEnumOrThrow <QuarterNumber>(tokens[1], errorMessage); try { var deserialized = new FiscalQuarter(year, quarter); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(FiscalYear)) { var year = ParseIntOrThrow(tokens[0], errorMessage); try { var deserialized = new FiscalYear(year); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(FiscalUnbounded)) { var deserialized = new FiscalUnbounded(); return(deserialized); } if (serializedType == typeof(GenericMonth)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var month = ParseEnumOrThrow <MonthNumber>(tokens[1], errorMessage); try { var deserialized = new GenericMonth(year, month); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(GenericQuarter)) { var year = ParseIntOrThrow(tokens[0], errorMessage); var quarter = ParseEnumOrThrow <QuarterNumber>(tokens[1], errorMessage); try { var deserialized = new GenericQuarter(year, quarter); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(GenericYear)) { var year = ParseIntOrThrow(tokens[0], errorMessage); try { var deserialized = new GenericYear(year); return(deserialized); } catch (ArgumentException) { throw new InvalidOperationException(errorMessage); } } if (serializedType == typeof(GenericUnbounded)) { var deserialized = new GenericUnbounded(); return(deserialized); } throw new NotSupportedException("this type of unit-of-time is not supported: " + serializedType); }
/// <summary> /// Converts the the specified unit-of-time into the most /// granular possible, but equivalent, reporting period. /// </summary> /// <param name="unitOfTime">The unit-of-time to operate on.</param> /// <returns> /// A reporting period that addresses the same set of time as <paramref name="unitOfTime"/>, /// but is the most granular version possible of that unit-of-time. /// </returns> /// <exception cref="ArgumentNullException"><paramref name="unitOfTime"/> is null.</exception> public static ReportingPeriod ToMostGranular( this UnitOfTime unitOfTime) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Unbounded) { var result = new ReportingPeriod(unitOfTime, unitOfTime); return(result); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Year) { if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { var calendarYear = unitOfTime as CalendarYear; var result = new ReportingPeriod(calendarYear.GetFirstCalendarDay(), calendarYear.GetLastCalendarDay()); return(result); } var year = unitOfTime as IHaveAYear; if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Fiscal) { // ReSharper disable once PossibleNullReferenceException var result = new ReportingPeriod(new FiscalMonth(year.Year, MonthNumber.One), new FiscalMonth(year.Year, MonthNumber.Twelve)); return(result); } if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Generic) { // ReSharper disable once PossibleNullReferenceException var result = new ReportingPeriod(new GenericMonth(year.Year, MonthNumber.One), new GenericMonth(year.Year, MonthNumber.Twelve)); return(result); } throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Quarter) { if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { var calendarQuarter = unitOfTime as CalendarQuarter; var result = new ReportingPeriod(calendarQuarter.GetFirstCalendarDay(), calendarQuarter.GetLastCalendarDay()); return(result); } var quarter = unitOfTime as IHaveAQuarter; // ReSharper disable once PossibleNullReferenceException var startMonth = (((int)quarter.QuarterNumber - 1) * 3) + 1; var endMonth = (int)quarter.QuarterNumber * 3; if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Fiscal) { var result = new ReportingPeriod(new FiscalMonth(quarter.Year, (MonthNumber)startMonth), new FiscalMonth(quarter.Year, (MonthNumber)endMonth)); return(result); } if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Generic) { var result = new ReportingPeriod(new GenericMonth(quarter.Year, (MonthNumber)startMonth), new GenericMonth(quarter.Year, (MonthNumber)endMonth)); return(result); } throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Month) { if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { var calendarMonth = unitOfTime as CalendarMonth; var result = new ReportingPeriod(calendarMonth.GetFirstCalendarDay(), calendarMonth.GetLastCalendarDay()); return(result); } if ((unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Fiscal) || (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Generic)) { var result = new ReportingPeriod(unitOfTime, unitOfTime); return(result); } throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Day) { if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { var result = new ReportingPeriod(unitOfTime, unitOfTime); return(result); } throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } throw new NotSupportedException("This granularity is not supported: " + unitOfTime.UnitOfTimeGranularity); }
public static UnitOfTime Plus( this UnitOfTime unitOfTime, int unitsToAdd, UnitOfTimeGranularity granularityOfUnitsToAdd) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Unbounded) { throw new ArgumentException(Invariant($"Cannot add or subtract from a unit-of-time whose granuarlity is {nameof(UnitOfTimeGranularity.Unbounded)}")); } if (granularityOfUnitsToAdd == UnitOfTimeGranularity.Invalid) { throw new ArgumentException(Invariant($"{nameof(granularityOfUnitsToAdd)} is {nameof(UnitOfTimeGranularity.Invalid)}")); } if (granularityOfUnitsToAdd == UnitOfTimeGranularity.Unbounded) { throw new ArgumentException(Invariant($"{nameof(granularityOfUnitsToAdd)} is {nameof(UnitOfTimeGranularity.Unbounded)}. Cannot add units of that granularity.")); } if (granularityOfUnitsToAdd.IsMoreGranularThan(unitOfTime.UnitOfTimeGranularity)) { throw new ArgumentException(Invariant($"{nameof(granularityOfUnitsToAdd)} is more granular than {nameof(unitOfTime)}. Only units that are as granular or less granular than a unit-of-time can be added to that unit-of-time.")); } if (unitOfTime.UnitOfTimeGranularity == granularityOfUnitsToAdd) { var result = unitOfTime.Plus(unitsToAdd); return(result); } if (granularityOfUnitsToAdd == UnitOfTimeGranularity.Year) { if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Quarter) { var result = unitOfTime.Plus(4 * unitsToAdd); return(result); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Month) { var result = unitOfTime.Plus(12 * unitsToAdd); return(result); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Day) { throw new NotSupportedException("adjusting a unit-of-time with Day granularity is not supported"); } throw new InvalidOperationException("should not get here"); } if (granularityOfUnitsToAdd == UnitOfTimeGranularity.Quarter) { if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Month) { var result = unitOfTime.Plus(3 * unitsToAdd); return(result); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Day) { throw new NotSupportedException("adjusting a unit-of-time with Day granularity is not supported"); } throw new InvalidOperationException("should not get here"); } if (granularityOfUnitsToAdd == UnitOfTimeGranularity.Month) { if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Day) { throw new NotSupportedException("adjusting a unit-of-time with Day granularity is not supported"); } throw new InvalidOperationException("should not get here"); } throw new InvalidOperationException("should not get here"); }
private static IReportingPeriod <UnitOfTime> MakeMoreGranular( this UnitOfTime unitOfTime, UnitOfTimeGranularity granularity) { if (unitOfTime == null) { throw new ArgumentNullException(nameof(unitOfTime)); } if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Unbounded) { throw new ArgumentException(Invariant($"{nameof(unitOfTime)} granularity is {nameof(UnitOfTimeGranularity.Unbounded)}")); } if (granularity == UnitOfTimeGranularity.Invalid) { throw new ArgumentException(Invariant($"{nameof(granularity)} is {nameof(UnitOfTimeGranularity.Invalid)}")); } if (granularity == UnitOfTimeGranularity.Unbounded) { throw new ArgumentException(Invariant($"{nameof(granularity)} is {nameof(UnitOfTimeGranularity.Unbounded)}")); } if (unitOfTime.UnitOfTimeGranularity.IsAsGranularOrMoreGranularThan(granularity)) { throw new ArgumentException(Invariant($"{nameof(unitOfTime)} is as granular or more granular than {nameof(granularity)}")); } IReportingPeriod <UnitOfTime> moreGranularReportingPeriod; if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Year) { var unitOfTimeAsYear = unitOfTime as IHaveAYear; var startQuarter = QuarterNumber.Q1; var endQuarter = QuarterNumber.Q4; if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { // ReSharper disable once PossibleNullReferenceException moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(new CalendarQuarter(unitOfTimeAsYear.Year, startQuarter), new CalendarQuarter(unitOfTimeAsYear.Year, endQuarter)); } else if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Fiscal) { // ReSharper disable once PossibleNullReferenceException moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(new FiscalQuarter(unitOfTimeAsYear.Year, startQuarter), new FiscalQuarter(unitOfTimeAsYear.Year, endQuarter)); } else if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Generic) { // ReSharper disable once PossibleNullReferenceException moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(new GenericQuarter(unitOfTimeAsYear.Year, startQuarter), new GenericQuarter(unitOfTimeAsYear.Year, endQuarter)); } else { throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } } else if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Quarter) { var unitOfTimeAsQuarter = unitOfTime as IHaveAQuarter; // ReSharper disable once PossibleNullReferenceException var startMonth = ((((int)unitOfTimeAsQuarter.QuarterNumber) - 1) * 3) + 1; var endMonth = ((int)unitOfTimeAsQuarter.QuarterNumber) * 3; if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(new CalendarMonth(unitOfTimeAsQuarter.Year, (MonthOfYear)startMonth), new CalendarMonth(unitOfTimeAsQuarter.Year, (MonthOfYear)endMonth)); } else if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Fiscal) { moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(new FiscalMonth(unitOfTimeAsQuarter.Year, (MonthNumber)startMonth), new FiscalMonth(unitOfTimeAsQuarter.Year, (MonthNumber)endMonth)); } else if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Generic) { moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(new GenericMonth(unitOfTimeAsQuarter.Year, (MonthNumber)startMonth), new GenericMonth(unitOfTimeAsQuarter.Year, (MonthNumber)endMonth)); } else { throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } } else if (unitOfTime.UnitOfTimeGranularity == UnitOfTimeGranularity.Month) { if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Calendar) { var calendarUnitOfTime = unitOfTime as CalendarUnitOfTime; moreGranularReportingPeriod = new ReportingPeriod <UnitOfTime>(calendarUnitOfTime.GetFirstCalendarDay(), calendarUnitOfTime.GetLastCalendarDay()); } else if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Fiscal) { throw new NotSupportedException("The Fiscal kind cannot be made more granular than Month."); } else if (unitOfTime.UnitOfTimeKind == UnitOfTimeKind.Generic) { throw new NotSupportedException("The Generic kind cannot be made more granular than Month."); } else { throw new NotSupportedException("This kind of unit-of-time is not supported: " + unitOfTime.UnitOfTimeKind); } } else { throw new NotSupportedException("This granularity is not supported: " + unitOfTime.UnitOfTimeGranularity); } if (moreGranularReportingPeriod.GetUnitOfTimeGranularity() == granularity) { return(moreGranularReportingPeriod); } var result = moreGranularReportingPeriod.MakeMoreGranular(granularity); return(result); }