Example #1
0
        public virtual string GetUnitText(TimeSpanFormatOptions unit, int value, bool abbr)
        {
            switch (unit)
            {
            case TimeSpanFormatOptions.RangeWeeks:
                return(getValue(PluralRule, value, abbr ? w : week));

            case TimeSpanFormatOptions.RangeDays:
                return(getValue(PluralRule, value, abbr ? d : day));

            case TimeSpanFormatOptions.RangeHours:
                return(getValue(PluralRule, value, abbr ? h : hour));

            case TimeSpanFormatOptions.RangeMinutes:
                return(getValue(PluralRule, value, abbr ? m : minute));

            case TimeSpanFormatOptions.RangeSeconds:
                return(getValue(PluralRule, value, abbr ? s : second));

            case TimeSpanFormatOptions.RangeMilliSeconds:
                return(getValue(PluralRule, value, abbr ? ms : millisecond));
            }

            // (should be unreachable)
            return(null);
        }
Example #2
0
        public static IEnumerable <TimeSpanFormatOptions> AllFlags(this TimeSpanFormatOptions timeSpanFormatOptions)
        {
            uint value = 0x1;

            while (value <= (uint)timeSpanFormatOptions)
            {
                if ((value & (uint)timeSpanFormatOptions) != 0)
                {
                    yield return((TimeSpanFormatOptions)value);
                }
                value <<= 1;
            }
        }
Example #3
0
 public virtual string GetUnitText(TimeSpanFormatOptions unit, int value, bool abbr)
 {
     return(unit switch
     {
         TimeSpanFormatOptions.RangeWeeks => GetValue(PluralRule, value, abbr ? w : week),
         TimeSpanFormatOptions.RangeDays => GetValue(PluralRule, value, abbr ? d : day),
         TimeSpanFormatOptions.RangeHours => GetValue(PluralRule, value, abbr ? h : hour),
         TimeSpanFormatOptions.RangeMinutes => GetValue(PluralRule, value, abbr ? m : minute),
         TimeSpanFormatOptions.RangeSeconds => GetValue(PluralRule, value, abbr ? s : second),
         TimeSpanFormatOptions.RangeMilliSeconds => GetValue(PluralRule, value, abbr ? ms : millisecond),
         // (should be unreachable)
         _ => string.Empty
     });
Example #4
0
        public static TimeSpanFormatOptions Merge(this TimeSpanFormatOptions left, TimeSpanFormatOptions right)
        {
            var masks = new[] {
                TimeSpanFormatOptions._Abbreviate,
                TimeSpanFormatOptions._LessThan,
                TimeSpanFormatOptions._Range,
                TimeSpanFormatOptions._Truncate,
            };

            foreach (var mask in masks)
            {
                if ((left & mask) == 0)
                {
                    left |= right & mask;
                }
            }
            return(left);
        }
Example #5
0
        /// <summary>
        /// Gets the text for <see cref="TimeSpanFormatOptions"/> ranges,
        /// that correspond to a certain value.
        /// </summary>
        /// <param name="unit"></param>
        /// <param name="value"></param>
        /// <param name="abbr"></param>
        /// <returns>
        /// The text for <see cref="TimeSpanFormatOptions"/> ranges,
        /// that correspond to a certain value.
        /// </returns>
        public virtual string GetUnitText(TimeSpanFormatOptions unit, int value, bool abbr)
        {
            if (PluralRule == null)
            {
                throw new InvalidOperationException("Plural rule delegate must not be null");
            }

            return(unit switch
            {
                TimeSpanFormatOptions.RangeWeeks => GetValue(PluralRule, value, abbr ? Ptxt_w : Ptxt_week),
                TimeSpanFormatOptions.RangeDays => GetValue(PluralRule, value, abbr ? Ptxt_d : Ptxt_day),
                TimeSpanFormatOptions.RangeHours => GetValue(PluralRule, value, abbr ? Ptxt_h : Ptxt_hour),
                TimeSpanFormatOptions.RangeMinutes => GetValue(PluralRule, value, abbr ? Ptxt_m : Ptxt_minute),
                TimeSpanFormatOptions.RangeSeconds => GetValue(PluralRule, value, abbr ? Ptxt_s : Ptxt_second),
                TimeSpanFormatOptions.RangeMilliSeconds => GetValue(PluralRule, value, abbr ? Ptxt_ms : Ptxt_millisecond),
                // (should be unreachable)
                _ => string.Empty
            });
        public static TimeSpanFormatOptions Merge(this TimeSpanFormatOptions left, TimeSpanFormatOptions right)
        {
            var masks = new[]
            {
                TimeSpanUtility.AbbreviateAll,
                TimeSpanUtility.LessThanAll,
                TimeSpanUtility.RangeAll,
                TimeSpanUtility.TruncateAll
            };

            foreach (var mask in masks)
            {
                if ((left & mask) == 0)
                {
                    left |= right & mask;
                }
            }
            return(left);
        }
Example #7
0
 public static TimeSpanFormatOptions Mask(this TimeSpanFormatOptions timeSpanFormatOptions,
                                          TimeSpanFormatOptions mask)
 {
     return(timeSpanFormatOptions & mask);
 }
Example #8
0
        /// <summary>
        /// <para>Turns a TimeSpan into a human-readable text.</para>
        /// <para>Uses the specified timeSpanFormatOptions.</para>
        /// <para>For example: "31.23:59:00.555" = "31 days 23 hours 59 minutes 0 seconds 555 milliseconds"</para>
        /// </summary>
        /// <param name="FromTime"></param>
        /// <param name="options">
        /// <para>A combination of flags that determine the formatting options.</para>
        /// <para>These will be combined with the default timeSpanFormatOptions.</para>
        /// </param>
        /// <param name="timeTextInfo">An object that supplies the text to use for output</param>
        public static string ToTimeString(this TimeSpan FromTime, TimeSpanFormatOptions options,
                                          TimeTextInfo timeTextInfo)
        {
            // If there are any missing options, merge with the defaults:
            // Also, as a safeguard against missing DefaultFormatOptions, let's also merge with the AbsoluteDefaults:
            options = options.Merge(DefaultFormatOptions).Merge(AbsoluteDefaults);
            // Extract the individual options:
            var rangeMax   = options.Mask(TimeSpanFormatOptions._Range).AllFlags().Last();
            var rangeMin   = options.Mask(TimeSpanFormatOptions._Range).AllFlags().First();
            var truncate   = options.Mask(TimeSpanFormatOptions._Truncate).AllFlags().First();
            var lessThan   = options.Mask(TimeSpanFormatOptions._LessThan) != TimeSpanFormatOptions.LessThanOff;
            var abbreviate = options.Mask(TimeSpanFormatOptions._Abbreviate) != TimeSpanFormatOptions.AbbreviateOff;

            var round = lessThan ? (Func <double, double>)Math.Floor : Math.Ceiling;

            switch (rangeMin)
            {
            case TimeSpanFormatOptions.RangeWeeks:
                FromTime = TimeSpan.FromDays(round(FromTime.TotalDays / 7) * 7);
                break;

            case TimeSpanFormatOptions.RangeDays:
                FromTime = TimeSpan.FromDays(round(FromTime.TotalDays));
                break;

            case TimeSpanFormatOptions.RangeHours:
                FromTime = TimeSpan.FromHours(round(FromTime.TotalHours));
                break;

            case TimeSpanFormatOptions.RangeMinutes:
                FromTime = TimeSpan.FromMinutes(round(FromTime.TotalMinutes));
                break;

            case TimeSpanFormatOptions.RangeSeconds:
                FromTime = TimeSpan.FromSeconds(round(FromTime.TotalSeconds));
                break;

            case TimeSpanFormatOptions.RangeMilliSeconds:
                FromTime = TimeSpan.FromMilliseconds(round(FromTime.TotalMilliseconds));
                break;
            }

            // Create our result:
            var textStarted = false;
            var result      = new StringBuilder();

            for (var i = rangeMax; i >= rangeMin; i = (TimeSpanFormatOptions)((int)i >> 1))
            {
                // Determine the value and title:
                int value;
                switch (i)
                {
                case TimeSpanFormatOptions.RangeWeeks:
                    value     = (int)Math.Floor(FromTime.TotalDays / 7);
                    FromTime -= TimeSpan.FromDays(value * 7);
                    break;

                case TimeSpanFormatOptions.RangeDays:
                    value     = (int)Math.Floor(FromTime.TotalDays);
                    FromTime -= TimeSpan.FromDays(value);
                    break;

                case TimeSpanFormatOptions.RangeHours:
                    value     = (int)Math.Floor(FromTime.TotalHours);
                    FromTime -= TimeSpan.FromHours(value);
                    break;

                case TimeSpanFormatOptions.RangeMinutes:
                    value     = (int)Math.Floor(FromTime.TotalMinutes);
                    FromTime -= TimeSpan.FromMinutes(value);
                    break;

                case TimeSpanFormatOptions.RangeSeconds:
                    value     = (int)Math.Floor(FromTime.TotalSeconds);
                    FromTime -= TimeSpan.FromSeconds(value);
                    break;

                case TimeSpanFormatOptions.RangeMilliSeconds:
                    value     = (int)Math.Floor(FromTime.TotalMilliseconds);
                    FromTime -= TimeSpan.FromMilliseconds(value);
                    break;

                default:
                    // This code is unreachable, but it prevents compile-errors.
                    throw new ArgumentException("TimeSpanUtility");
                }


                //Determine whether to display this value
                var displayThisValue = false;
                var breakFor         =
                    false; // I wish C# supported "break for;" (like how VB supports "Exit For" from within a "Select Case" statement)
                switch (truncate)
                {
                case TimeSpanFormatOptions.TruncateShortest:
                    if (textStarted)
                    {
                        breakFor = true;
                        break;
                    }

                    if (value > 0)
                    {
                        displayThisValue = true;
                    }
                    break;

                case TimeSpanFormatOptions.TruncateAuto:
                    if (value > 0)
                    {
                        displayThisValue = true;
                    }
                    break;

                case TimeSpanFormatOptions.TruncateFill:
                    if (textStarted || value > 0)
                    {
                        displayThisValue = true;
                    }
                    break;

                case TimeSpanFormatOptions.TruncateFull:
                    displayThisValue = true;
                    break;
                }

                if (breakFor)
                {
                    break;
                }

                //we need to display SOMETHING (even if it's zero)
                if (i == rangeMin && textStarted == false)
                {
                    displayThisValue = true;
                    if (lessThan && value < 1)
                    {
                        // Output the "less than 1 unit" text:
                        var unitTitle = timeTextInfo.GetUnitText(rangeMin, 1, abbreviate);
                        result.Append(timeTextInfo.GetLessThanText(unitTitle));
                        displayThisValue = false;
                    }
                }

                // Output the value:
                if (displayThisValue)
                {
                    if (textStarted)
                    {
                        result.Append(" ");
                    }
                    var unitTitle = timeTextInfo.GetUnitText(i, value, abbreviate);
                    result.Append(unitTitle);
                    textStarted = true;
                }
            }

            return(result.ToString());
        }
Example #9
0
        /// <summary>
        /// <para>Turns a TimeSpan into a human-readable text.</para>
        /// <para>Uses the specified timeSpanFormatOptions.</para>
        /// <para>For example: "31.23:59:00.555" = "31 days 23 hours 59 minutes 0 seconds 555 milliseconds"</para>
        /// </summary>
        /// <param name="fromTime"></param>
        /// <param name="options">
        /// <para>A combination of flags that determine the formatting options.</para>
        /// <para>These will be combined with the default timeSpanFormatOptions.</para>
        /// </param>
        /// <param name="timeTextInfo">An object that supplies the text to use for output</param>
        public static string ToTimeString(this TimeSpan fromTime, TimeSpanFormatOptions options,
                                          TimeTextInfo timeTextInfo)
        {
            // If there are any missing options, merge with the defaults:
            // Also, as a safeguard against missing DefaultFormatOptions, let's also merge with the AbsoluteDefaults:
            options = options.Merge(DefaultFormatOptions).Merge(AbsoluteDefaults);

            // Extract the individual options:
            var rangeMax = options.Mask(TimeSpanFormatOptions._Range).AllFlags().Last();

            _rangeMin     = options.Mask(TimeSpanFormatOptions._Range).AllFlags().First();
            _truncate     = options.Mask(TimeSpanFormatOptions._Truncate).AllFlags().First();
            _lessThan     = options.Mask(TimeSpanFormatOptions._LessThan) != TimeSpanFormatOptions.LessThanOff;
            _abbreviate   = options.Mask(TimeSpanFormatOptions._Abbreviate) != TimeSpanFormatOptions.AbbreviateOff;
            _round        = _lessThan ? (Func <double, double>)Math.Floor : Math.Ceiling;
            _timeTextInfo = timeTextInfo;

            switch (_rangeMin)
            {
            case TimeSpanFormatOptions.RangeWeeks:
                fromTime = TimeSpan.FromDays(_round(fromTime.TotalDays / 7) * 7);
                break;

            case TimeSpanFormatOptions.RangeDays:
                fromTime = TimeSpan.FromDays(_round(fromTime.TotalDays));
                break;

            case TimeSpanFormatOptions.RangeHours:
                fromTime = TimeSpan.FromHours(_round(fromTime.TotalHours));
                break;

            case TimeSpanFormatOptions.RangeMinutes:
                fromTime = TimeSpan.FromMinutes(_round(fromTime.TotalMinutes));
                break;

            case TimeSpanFormatOptions.RangeSeconds:
                fromTime = TimeSpan.FromSeconds(_round(fromTime.TotalSeconds));
                break;

            case TimeSpanFormatOptions.RangeMilliSeconds:
                fromTime = TimeSpan.FromMilliseconds(_round(fromTime.TotalMilliseconds));
                break;
            }

            // Create our result:
            var textStarted = false;
            var result      = new StringBuilder();

            for (var i = rangeMax; i >= _rangeMin; i = (TimeSpanFormatOptions)((int)i >> 1))
            {
                // Determine the value and title:
                int value;
                switch (i)
                {
                case TimeSpanFormatOptions.RangeWeeks:
                    value     = (int)Math.Floor(fromTime.TotalDays / 7);
                    fromTime -= TimeSpan.FromDays(value * 7);
                    break;

                case TimeSpanFormatOptions.RangeDays:
                    value     = (int)Math.Floor(fromTime.TotalDays);
                    fromTime -= TimeSpan.FromDays(value);
                    break;

                case TimeSpanFormatOptions.RangeHours:
                    value     = (int)Math.Floor(fromTime.TotalHours);
                    fromTime -= TimeSpan.FromHours(value);
                    break;

                case TimeSpanFormatOptions.RangeMinutes:
                    value     = (int)Math.Floor(fromTime.TotalMinutes);
                    fromTime -= TimeSpan.FromMinutes(value);
                    break;

                case TimeSpanFormatOptions.RangeSeconds:
                    value     = (int)Math.Floor(fromTime.TotalSeconds);
                    fromTime -= TimeSpan.FromSeconds(value);
                    break;

                case TimeSpanFormatOptions.RangeMilliSeconds:
                    value     = (int)Math.Floor(fromTime.TotalMilliseconds);
                    fromTime -= TimeSpan.FromMilliseconds(value);
                    break;

                default:
                    // Should never happen. Ensures 'value' and 'fromTime' are always set.
                    continue;
                }

                //Determine whether to display this value
                if (!ShouldTruncate(value, textStarted, out var displayThisValue))
                {
                    continue;
                }

                PrepareOutput(value, i == _rangeMin, textStarted, result, ref displayThisValue);

                // Output the value:
                if (displayThisValue)
                {
                    if (textStarted)
                    {
                        result.Append(' ');
                    }
                    var unitTitle = _timeTextInfo.GetUnitText(i, value, _abbreviate);
                    result.Append(unitTitle);
                    textStarted = true;
                }
            }

            return(result.ToString());
        }
		/// <summary>
		///   <para>Turns a TimeSpan into a human-readable text.</para>
		///   <para>Uses the specified timeSpanFormatOptions.</para>
		///   <para>For example: "31.23:59:00.555" = "31 days 23 hours 59 minutes 0 seconds 555 milliseconds"</para>
		/// </summary>
		/// <param name="FromTime"></param>
		/// <param name="options">
		///   <para>A combination of flags that determine the formatting options.</para>
		///   <para>These will be combined with the default timeSpanFormatOptions.</para>
		/// </param>
		/// <param name="timeTextInfo">An object that supplies the text to use for output</param>
		public static string ToTimeString(this TimeSpan FromTime, TimeSpanFormatOptions options, TimeTextInfo timeTextInfo)
		{
			// If there are any missing options, merge with the defaults:
			// Also, as a safeguard against missing DefaultFormatOptions, let's also merge with the AbsoluteDefaults:
			options = options.Merge(DefaultFormatOptions).Merge(AbsoluteDefaults);
			// Extract the individual options:
			var rangeMax = options.Mask(TimeSpanFormatOptions._Range).AllFlags().Last();
			var rangeMin = options.Mask(TimeSpanFormatOptions._Range).AllFlags().First();
			var truncate = options.Mask(TimeSpanFormatOptions._Truncate).AllFlags().First();
			var lessThan = options.Mask(TimeSpanFormatOptions._LessThan) != TimeSpanFormatOptions.LessThanOff;
			var abbreviate = options.Mask(TimeSpanFormatOptions._Abbreviate) != TimeSpanFormatOptions.AbbreviateOff;

			var round = (lessThan ? (Func<double, double>)Math.Floor : Math.Ceiling);
			switch (rangeMin) {
				case TimeSpanFormatOptions.RangeWeeks:
					FromTime = TimeSpan.FromDays(round(FromTime.TotalDays / 7) * 7);
					break;
				case TimeSpanFormatOptions.RangeDays:
					FromTime = TimeSpan.FromDays(round(FromTime.TotalDays));
					break;
				case TimeSpanFormatOptions.RangeHours:
					FromTime = TimeSpan.FromHours(round(FromTime.TotalHours));
					break;
				case TimeSpanFormatOptions.RangeMinutes:
					FromTime = TimeSpan.FromMinutes(round(FromTime.TotalMinutes));
					break;
				case TimeSpanFormatOptions.RangeSeconds:
					FromTime = TimeSpan.FromSeconds(round(FromTime.TotalSeconds));
					break;
				case TimeSpanFormatOptions.RangeMilliSeconds:
					FromTime = TimeSpan.FromMilliseconds(round(FromTime.TotalMilliseconds));
					break;
			}

			// Create our result:
			bool textStarted = false;
			var result = new StringBuilder();
			for (var i = rangeMax; i >= rangeMin; i=(TimeSpanFormatOptions)((int)i>>1)) {
				// Determine the value and title:
				int value;
				switch (i) {
					case TimeSpanFormatOptions.RangeWeeks:
						value = (int)Math.Floor(FromTime.TotalDays / 7);
						FromTime -= TimeSpan.FromDays(value * 7);
						break;
					case TimeSpanFormatOptions.RangeDays:
						value = (int)Math.Floor(FromTime.TotalDays);
						FromTime -= TimeSpan.FromDays(value);
						break;
					case TimeSpanFormatOptions.RangeHours:
						value = (int)Math.Floor(FromTime.TotalHours);
						FromTime -= TimeSpan.FromHours(value);
						break;
					case TimeSpanFormatOptions.RangeMinutes:
						value = (int)Math.Floor(FromTime.TotalMinutes);
						FromTime -= TimeSpan.FromMinutes(value);
						break;
					case TimeSpanFormatOptions.RangeSeconds:
						value = (int)Math.Floor(FromTime.TotalSeconds);
						FromTime -= TimeSpan.FromSeconds(value);
						break;
					case TimeSpanFormatOptions.RangeMilliSeconds:
						value = (int)Math.Floor(FromTime.TotalMilliseconds);
						FromTime -= TimeSpan.FromMilliseconds(value);
						break;
					default:
						// This code is unreachable, but it prevents compile-errors.
						throw new ArgumentException("TimeSpanUtility");
				}


				//Determine whether to display this value
				bool displayThisValue = false;
				bool breakFor = false; // I wish C# supported "break for;" (like how VB supports "Exit For" from within a "Select Case" statement)
				switch (truncate)
				{
					case TimeSpanFormatOptions.TruncateShortest:
						if (textStarted)
						{
							breakFor = true;
							break;
						}
						if (value > 0) displayThisValue = true;
						break;
					case TimeSpanFormatOptions.TruncateAuto:
						if (value > 0) displayThisValue = true;
						break;
					case TimeSpanFormatOptions.TruncateFill:
						if (textStarted || value > 0) displayThisValue = true;
						break;
					case TimeSpanFormatOptions.TruncateFull:
						displayThisValue = true;
						break;
				}
				if (breakFor) break;

				//we need to display SOMETHING (even if it's zero)
				if (i == rangeMin && textStarted == false) {
					displayThisValue = true;
					if (lessThan && value < 1) {
						// Output the "less than 1 unit" text:
						var unitTitle = timeTextInfo.GetUnitText(rangeMin, 1, abbreviate);
						result.Append(timeTextInfo.GetLessThanText(unitTitle));
						displayThisValue = false;
					}
				}

				// Output the value:
				if (displayThisValue) {
					if (textStarted) result.Append(" ");
					var unitTitle = timeTextInfo.GetUnitText(i, value, abbreviate);
					result.Append(unitTitle);
					textStarted = true;
				}
			}

			return result.ToString();
		}
		public virtual string GetUnitText(TimeSpanFormatOptions unit, int value, bool abbr)
		{
			switch (unit)
			{
				case TimeSpanFormatOptions.RangeWeeks:
					return getValue(PluralRule, value, abbr ? w : week);
				case TimeSpanFormatOptions.RangeDays:
					return getValue(PluralRule, value, abbr ? d : day);
				case TimeSpanFormatOptions.RangeHours:
					return getValue(PluralRule, value, abbr ? h : hour);
				case TimeSpanFormatOptions.RangeMinutes:
					return getValue(PluralRule, value, abbr ? m : minute);
				case TimeSpanFormatOptions.RangeSeconds:
					return getValue(PluralRule, value, abbr ? s : second);
				case TimeSpanFormatOptions.RangeMilliSeconds:
					return getValue(PluralRule, value, abbr ? ms : millisecond);
			}

			// (should be unreachable)
			return null;
		}
		public static TimeSpanFormatOptions Mask(this TimeSpanFormatOptions timeSpanFormatOptions, TimeSpanFormatOptions mask)
		{
			return timeSpanFormatOptions & mask;
		}
		public static TimeSpanFormatOptions Merge(this TimeSpanFormatOptions left, TimeSpanFormatOptions right)
		{
			var masks = new[]{
					TimeSpanFormatOptions._Abbreviate,
					TimeSpanFormatOptions._LessThan,
					TimeSpanFormatOptions._Range,
					TimeSpanFormatOptions._Truncate,
				};
			foreach (var mask in masks)
			{
				if ((left & mask) == 0) left |= right & mask;
			}
			return left;
		}