예제 #1
0
        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);
        }
예제 #4
0
        /// <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);
        }
예제 #6
0
        /// <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());
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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;
        }
예제 #10
0
        /// <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);
            }
        }
예제 #11
0
        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");
        }
예제 #14
0
        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);
        }