Supplies the localized text used for TimeSpan formatting.
예제 #1
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());
        }
		/// <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();
		}