| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 | using System;using System.Collections.Generic;namespace InABox.Core{    /// <summary>    ///     Custom string formatter for TimeSpan that allows easy retrieval of Total segments.    /// </summary>    /// <example>    ///     TimeSpan myTimeSpan = new TimeSpan(27, 13, 5);    ///     string.Format("{0:th,###}h {0:mm}m {0:ss}s", myTimeSpan) -> "27h 13m 05s"    ///     string.Format("{0:TH}", myTimeSpan) -> "27.2180555555556"    ///     NOTE: myTimeSpan.ToString("TH") does not work.  See Remarks.    /// </example>    /// <remarks>    ///     Due to a quirk of .NET Framework (up through version 4.5.1),    ///     <code>TimeSpan.ToString(format, new TimeSpanFormatter())</code> will not work; it will always call    ///     TimeSpanFormat.FormatCustomized() which takes a DateTimeFormatInfo rather than an    ///     IFormatProvider/ICustomFormatter.  DateTimeFormatInfo, unfortunately, is a sealed class.    /// </remarks>    public class TimeSpanFormatter : IFormatProvider, ICustomFormatter    {        /// <summary>        ///     Used to create a wrapper format string with the specified format.        /// </summary>        private const string DefaultFormat = "{{0:{0}}}";        /// <summary>        ///     Determines whether the specified format is looking for a total, and formats it accordingly.        ///     If not, returns the default format for the given        ///     <para>format</para>        ///     of a TimeSpan.        /// </summary>        /// <returns>        ///     The formatted string for the given TimeSpan.        /// </returns>        /// <remarks>        ///     ICustomFormatter.Format implementation.        /// </remarks>        public string Format(string format, object arg, IFormatProvider formatProvider)        {            // only apply our format if there is a format and if the argument is a TimeSpan            if (string.IsNullOrWhiteSpace(format) ||                formatProvider != this || // this should always be true, but just in case...                !(arg is TimeSpan) ||                arg == null)                // return the default for whatever our format and argument are                return GetDefault(format, arg);            var span = (TimeSpan)arg;            var formatSegments = format.Split(new[] { ',' }, 2);            var tsFormat = formatSegments[0].ToLower();            if (!string.IsNullOrWhiteSpace(tsFormat))            {                var results = new List<string>();                var segments = tsFormat.Replace("\\", "").Split(':');                try                {                    foreach (var segment in segments)                        if (segment.Equals("d"))                            results.Add(span.Days.ToString());                        else if (segment.Equals("dd"))                            results.Add(span.Days.ToString("D2"));                        else if (segment.Equals("h"))                            results.Add(span.Hours.ToString());                        else if (segment.Equals("hh"))                            results.Add(span.Hours.ToString("D2"));                        else if (segment.Equals("hhh"))                            results.Add(((int)span.TotalHours).ToString());                        else if (segment.Equals("mm"))                            results.Add(span.Minutes.ToString("D2"));                        else if (segment.Equals("ss"))                            results.Add(span.Seconds.ToString("D2"));                        else if (segment.Equals("zzz"))                            results.Add(span.Milliseconds.ToString("D3"));                    return string.Join(":", results);                }                catch (Exception e)                {                    return GetDefault(format, arg);                }            }            return span.ToString();        }        /// <remarks>        ///     IFormatProvider.GetFormat implementation.        /// </remarks>        public object GetFormat(Type formatType)        {            // Determine whether custom formatting object is requested.             if (formatType == typeof(ICustomFormatter)) return this;            return null;        }        /// <summary>        ///     Returns the formatted value when we don't know what to do with their specified format.        /// </summary>        private string GetDefault(string format, object arg)        {            return string.Format(string.Format(DefaultFormat, format), arg);        }    }}
 |