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 IEnumerable <TimeSpanFormatOptions> AllFlags(this TimeSpanFormatOptions timeSpanFormatOptions) { uint value = 0x1; while (value <= (uint)timeSpanFormatOptions) { if ((value & (uint)timeSpanFormatOptions) != 0) { yield return((TimeSpanFormatOptions)value); } value <<= 1; } }
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 });
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); }
/// <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); }
public static TimeSpanFormatOptions Mask(this TimeSpanFormatOptions timeSpanFormatOptions, TimeSpanFormatOptions mask) { return(timeSpanFormatOptions & mask); }
/// <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()); }
/// <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; }