How can I String.Format a TimeSpan object with a custom format in .NET?

后端 未结 19 1229
情深已故
情深已故 2020-11-22 12:25

What is the recommended way of formatting TimeSpan objects into a string with a custom format?

19条回答
  •  囚心锁ツ
    2020-11-22 12:39

    Here is my version. It shows only as much as necessary, handles pluralization, negatives, and I tried to make it lightweight.

    Output Examples

    0 seconds
    1.404 seconds
    1 hour, 14.4 seconds
    14 hours, 57 minutes, 22.473 seconds
    1 day, 14 hours, 57 minutes, 22.475 seconds
    

    Code

    public static class TimeSpanExtensions
    {
        public static string ToReadableString(this TimeSpan timeSpan)
        {
            int days = (int)(timeSpan.Ticks / TimeSpan.TicksPerDay);
            long subDayTicks = timeSpan.Ticks % TimeSpan.TicksPerDay;
    
            bool isNegative = false;
            if (timeSpan.Ticks < 0L)
            {
                isNegative = true;
                days = -days;
                subDayTicks = -subDayTicks;
            }
    
            int hours = (int)((subDayTicks / TimeSpan.TicksPerHour) % 24L);
            int minutes = (int)((subDayTicks / TimeSpan.TicksPerMinute) % 60L);
            int seconds = (int)((subDayTicks / TimeSpan.TicksPerSecond) % 60L);
            int subSecondTicks = (int)(subDayTicks % TimeSpan.TicksPerSecond);
            double fractionalSeconds = (double)subSecondTicks / TimeSpan.TicksPerSecond;
    
            var parts = new List(4);
    
            if (days > 0)
                parts.Add(string.Format("{0} day{1}", days, days == 1 ? null : "s"));
            if (hours > 0)
                parts.Add(string.Format("{0} hour{1}", hours, hours == 1 ? null : "s"));
            if (minutes > 0)
                parts.Add(string.Format("{0} minute{1}", minutes, minutes == 1 ? null : "s"));
            if (fractionalSeconds.Equals(0D))
            {
                switch (seconds)
                {
                    case 0:
                        // Only write "0 seconds" if we haven't written anything at all.
                        if (parts.Count == 0)
                            parts.Add("0 seconds");
                        break;
    
                    case 1:
                        parts.Add("1 second");
                        break;
    
                    default:
                        parts.Add(seconds + " seconds");
                        break;
                }
            }
            else
            {
                parts.Add(string.Format("{0}{1:.###} seconds", seconds, fractionalSeconds));
            }
    
            string resultString = string.Join(", ", parts);
            return isNegative ? "(negative) " + resultString : resultString;
        }
    }
    

提交回复
热议问题