private static FiscalMonth Plus(
            this FiscalMonth unitOfTime,
            int unitsToAdd)
        {
            var genericMonth = unitOfTime.ToGenericMonth().Plus(unitsToAdd);
            var result       = new FiscalMonth(genericMonth.Year, genericMonth.MonthNumber);

            return(result);
        }
示例#2
0
        public static UnitOfTime DeserializeFromSortableString(
            this string unitOfTime,
            Type type)
        {
            if (!type.IsUnitOfTimeType())
            {
                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(Invariant($"'{nameof(unitOfTime)}' is white space"));
            }

            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 result = new CalendarDay(year, month, day);

                    return(result);
                }
                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 result = new CalendarMonth(year, month);

                    return(result);
                }
                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 result = new CalendarQuarter(year, quarter);

                    return(result);
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (serializedType == typeof(CalendarYear))
            {
                var year = ParseIntOrThrow(tokens[0], errorMessage);

                try
                {
                    var result = new CalendarYear(year);

                    return(result);
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (serializedType == typeof(CalendarUnbounded))
            {
                var result = new CalendarUnbounded();

                return(result);
            }

            if (serializedType == typeof(FiscalMonth))
            {
                var year  = ParseIntOrThrow(tokens[0], errorMessage);
                var month = ParseEnumOrThrow <MonthNumber>(tokens[1], errorMessage);

                try
                {
                    var result = new FiscalMonth(year, month);

                    return(result);
                }
                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 result = new FiscalQuarter(year, quarter);

                    return(result);
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (serializedType == typeof(FiscalYear))
            {
                var year = ParseIntOrThrow(tokens[0], errorMessage);

                try
                {
                    var result = new FiscalYear(year);

                    return(result);
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (serializedType == typeof(FiscalUnbounded))
            {
                var result = new FiscalUnbounded();

                return(result);
            }

            if (serializedType == typeof(GenericMonth))
            {
                var year  = ParseIntOrThrow(tokens[0], errorMessage);
                var month = ParseEnumOrThrow <MonthNumber>(tokens[1], errorMessage);

                try
                {
                    var result = new GenericMonth(year, month);

                    return(result);
                }
                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 result = new GenericQuarter(year, quarter);

                    return(result);
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (serializedType == typeof(GenericYear))
            {
                var year = ParseIntOrThrow(tokens[0], errorMessage);

                try
                {
                    var result = new GenericYear(year);

                    return(result);
                }
                catch (ArgumentException)
                {
                    throw new InvalidOperationException(errorMessage);
                }
            }

            if (serializedType == typeof(GenericUnbounded))
            {
                var result = new GenericUnbounded();

                return(result);
            }

            throw new NotSupportedException("this type of unit-of-time is not supported: " + serializedType);
        }