public static decimal IntegerRound(decimal amount, IntegerRounding rounding) { var rounded = Math.Round(amount); if (rounding.MinimalAmount == 1) { return(rounded); } Func <decimal, decimal> roundingMethod; switch (rounding.Mode) { case IntegerRoundingMode.Ceiling: roundingMethod = Math.Ceiling; break; case IntegerRoundingMode.Floor: roundingMethod = Math.Floor; break; case IntegerRoundingMode.Round: roundingMethod = Math.Round; break; default: roundingMethod = Math.Round; break; } return(roundingMethod(rounded / rounding.MinimalAmount) * rounding.MinimalAmount); }
private static UnitValue GetUnitValue(TimeSpan value, IntegerRounding rounding, TimeSpanUnit unit) { double doubleValue = GetDouble(value, unit); //int valueRoundedDown = GetInteger(doubleValue, DefaultRounding); //int valueWithLowestUnitRounding = GetInteger(doubleValue, rounding); int valueRounded = GetInteger(doubleValue, rounding); return(new UnitValue(doubleValue, unit, valueRounded)); //Down, valueWithLowestUnitRounding); }
private static int GetInteger(double doubleValue, IntegerRounding rounding) { switch (rounding) { case IntegerRounding.Down: return((int)doubleValue); case IntegerRounding.ToNearestOrUp: return(Convert.ToInt32(doubleValue)); case IntegerRounding.Up: return((int)Math.Ceiling(doubleValue)); default: throw new NotImplementedException("IntegerRounding: " + rounding); } }
private static TimeSpan GetTimeSpanWithLowestUnitRounded(TimeSpan value, TimeSpanUnit lowestUnit, IntegerRounding lowestUnitRounding) { int lowestUnitValueRounded = GetInteger(GetDouble(value, lowestUnit), lowestUnitRounding); // Round the lowest unit, then reconstruct TimeSpan to round 60 seconds to 1 minute etc. int days = value.Days, hours = value.Hours, minutes = value.Minutes, seconds = value.Seconds, milliseconds = value.Milliseconds; switch (lowestUnit) { case TimeSpanUnit.Days: days = lowestUnitValueRounded; hours = minutes = seconds = milliseconds = 0; break; case TimeSpanUnit.Hours: hours = lowestUnitValueRounded; minutes = seconds = milliseconds = 0; break; case TimeSpanUnit.Minutes: minutes = lowestUnitValueRounded; seconds = milliseconds = 0; break; case TimeSpanUnit.Seconds: seconds = lowestUnitValueRounded; milliseconds = 0; break; case TimeSpanUnit.Milliseconds: milliseconds = lowestUnitValueRounded; break; } value = new TimeSpan(days, hours, minutes, seconds, milliseconds); return(value); }
public string RoundsLowestUnitAsSpecified(double hours, IntegerRounding rounding) { return(TimeSpan.FromHours(hours).ToPrettyString(lowestUnitRounding: rounding)); }
/// <summary> /// Returns a human readable string from TimeSpan, with a max number of parts to include. Units are included from /// largest to smallest. /// </summary> /// <param name="value">Time span value.</param> /// <param name="maxUnitGroups"> /// The max number of timespan units to use. /// </param> /// <param name="lowestUnit">Lowest unit to include in string.</param> /// <param name="rep"></param> /// <param name="highestUnit">Highest unit to include in string.</param> /// <param name="lowestUnitRounding">Rounding behavior of <paramref name="lowestUnit" />.</param> /// <param name="formatProvider">Specify the formatProvider used to .ToString() the numeric values.</param> /// <returns>Human readable string.</returns> public static string ToPrettyString(this TimeSpan value, int maxUnitGroups = 1, UnitStringRepresentation rep = UnitStringRepresentation.Long, TimeSpanUnit highestUnit = TimeSpanUnit.Days, TimeSpanUnit lowestUnit = TimeSpanUnit.Seconds, IntegerRounding lowestUnitRounding = IntegerRounding.ToNearestOrUp, IFormatProvider formatProvider = null) { if (maxUnitGroups <= 0) { maxUnitGroups = 1; } TimeFormat timeFormat; if (!Formats.TryGetValue(rep, out timeFormat)) { throw new NotImplementedException("UnitStringRepresentation: " + rep); } if (value == TimeSpan.Zero) { return(GetUnitValueString(0, lowestUnit, timeFormat, rep, formatProvider)); } //int days = value.Days, // hours = value.Hours, // minutes = value.Minutes, // seconds = value.Seconds, // milliseconds = value.Milliseconds; //if (highestUnit < TimeSpanUnit.Days || lowestUnit > TimeSpanUnit.Days) // days = 0; //if (highestUnit < TimeSpanUnit.Hours || lowestUnit > TimeSpanUnit.Hours) // hours = 0; //if (highestUnit < TimeSpanUnit.Minutes || lowestUnit > TimeSpanUnit.Minutes) // minutes = 0; //if (highestUnit < TimeSpanUnit.Seconds || lowestUnit > TimeSpanUnit.Seconds) // seconds = 0; //if (highestUnit < TimeSpanUnit.Milliseconds || lowestUnit > TimeSpanUnit.Milliseconds) // milliseconds = 0; // Trim off any values outside range TimeSpan trimmedValue = value; //new TimeSpan(days, hours, minutes, seconds, milliseconds); //var roundedValue = GetRoundedValue(trimmedValue, highestUnit, lowestUnit, lowestUnitRounding, maxUnitGroups); IList <UnitValue> nonZeroUnitValues = GetNonZeroUnitValues(trimmedValue, highestUnit, lowestUnit, lowestUnitRounding, maxUnitGroups) .RoundUnitsUp(); if (!nonZeroUnitValues.Any()) { // Value is zero or near zero. Fall back to lowest unit. // Example: 0.1 seconds when lowest unit is seconds int nearZeroValueRounded = GetInteger(GetDouble(value, lowestUnit), lowestUnitRounding); return(GetUnitValueString(nearZeroValueRounded, lowestUnit, timeFormat, rep, formatProvider)); } List <string> unitStrings = nonZeroUnitValues .Select((uv, i) => GetUnitValueString(uv.Value, uv.Unit, timeFormat, rep, formatProvider)) .ToList(); // Example: "3 hours" if (unitStrings.Count == 1) { return(unitStrings.First()); } // Example: "1 weeks, 2 days" string firstParts = string.Join(timeFormat.GroupSeparator, unitStrings.Take(unitStrings.Count - 1).ToArray()); // Example: "3 hours" string lastPart = unitStrings.Last(); // Example: "1 weeks, 2 days and 3 hours" return(firstParts + timeFormat.LastGroupSeparator + lastPart); }
private static IList <UnitValue> GetNonZeroUnitValues(TimeSpan value, TimeSpanUnit highestUnit, TimeSpanUnit lowestUnit, IntegerRounding lowestUnitRounding, int maxUnitGroups) { value = GetTimeSpanWithLowestUnitRounded(value, lowestUnit, lowestUnitRounding); IList <UnitValue> unitValues = UnitsLargeToSmall .Where(unit => unit <= highestUnit && unit >= lowestUnit) .Select(unit => GetUnitValue(value, DefaultRounding, unit)) .Where(unitValue => unitValue.Value >= 1) .Take(maxUnitGroups) .ToList(); if (!unitValues.Any()) { return(unitValues); } UnitValue last = unitValues.Last(); // ReSharper disable once CompareOfFloatsByEqualityOperator if (last.DoubleValue == 0) { return(unitValues); } List <UnitValue> unitValuesWithLastUnitRoundedUp = unitValues .Take(unitValues.Count - 1) .Concat(new[] { GetUnitValue(value, lowestUnitRounding, last.Unit) }) .ToList(); return(unitValuesWithLastUnitRoundedUp); }