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

后端 未结 19 1272
情深已故
情深已故 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:36

    If you want the duration format similar to youtube, given the number of seconds

    int[] duration = { 0, 4, 40, 59, 60, 61, 400, 4000, 40000, 400000 };
    foreach (int d in duration)
    {
        Console.WriteLine("{0, 6} -> {1, 10}", d, d > 59 ? TimeSpan.FromSeconds(d).ToString().TrimStart("00:".ToCharArray()) : string.Format("0:{0:00}", d));
    }
    

    Output:

         0 ->       0:00
         4 ->       0:04
        40 ->       0:40
        59 ->       0:59
        60 ->       1:00
        61 ->       1:01
       400 ->       6:40
      4000 ->    1:06:40
     40000 ->   11:06:40
    400000 -> 4.15:06:40
    
    0 讨论(0)
  • 2020-11-22 12:36

    I wanted to return a string such as "1 day 2 hours 3 minutes" and also take into account if for example days or minuttes are 0 and then not showing them. thanks to John Rasch for his answer which mine is barely an extension of

    TimeSpan timeLeft = New Timespan(0, 70, 0);
    String.Format("{0}{1}{2}{3}{4}{5}",
        Math.Floor(timeLeft.TotalDays) == 0 ? "" : 
        Math.Floor(timeLeft.TotalDays).ToString() + " ",
        Math.Floor(timeLeft.TotalDays) == 0 ? "" : Math.Floor(timeLeft.TotalDays) == 1 ? "day " : "days ",
        timeLeft.Hours == 0 ? "" : timeLeft.Hours.ToString() + " ",
        timeLeft.Hours == 0 ? "" : timeLeft.Hours == 1 ? "hour " : "hours ",
        timeLeft.Minutes == 0 ? "" : timeLeft.Minutes.ToString() + " ",
        timeLeft.Minutes == 0 ? "" : timeLeft.Minutes == 1 ? "minute " : "minutes ");
    
    0 讨论(0)
  • 2020-11-22 12:39

    The Substring method works perfectly when you only want the Hours:Minutes:Seconds. It's simple, clean code and easy to understand.

        var yourTimeSpan = DateTime.Now - DateTime.Now.AddMinutes(-2);
    
        var formatted = yourTimeSpan.ToString().Substring(0,8);// 00:00:00 
    
        Console.WriteLine(formatted);
    
    0 讨论(0)
  • 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<string>(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;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:40

    I use this method. I'm Belgian and speak dutch so plural of hours and minutes is not just adding 's' to the end but almost a different word than singular.

    It may seem long but it is very readable I think:

     public static string SpanToReadableTime(TimeSpan span)
        {
            string[] values = new string[4];  //4 slots: days, hours, minutes, seconds
            StringBuilder readableTime = new StringBuilder();
    
            if (span.Days > 0)
            {
                if (span.Days == 1)
                    values[0] = span.Days.ToString() + " dag"; //day
                else
                    values[0] = span.Days.ToString() + " dagen";  //days
    
                readableTime.Append(values[0]);
                readableTime.Append(", ");
            }
            else
                values[0] = String.Empty;
    
    
            if (span.Hours > 0)
            {
                if (span.Hours == 1)
                    values[1] = span.Hours.ToString() + " uur";  //hour
                else
                    values[1] = span.Hours.ToString() + " uren";  //hours
    
                readableTime.Append(values[1]);
                readableTime.Append(", ");
    
            }
            else
                values[1] = string.Empty;
    
            if (span.Minutes > 0)
            {
                if (span.Minutes == 1)
                    values[2] = span.Minutes.ToString() + " minuut";  //minute
                else
                    values[2] = span.Minutes.ToString() + " minuten";  //minutes
    
                readableTime.Append(values[2]);
                readableTime.Append(", ");
            }
            else
                values[2] = string.Empty;
    
            if (span.Seconds > 0)
            {
                if (span.Seconds == 1)
                    values[3] = span.Seconds.ToString() + " seconde";  //second
                else
                    values[3] = span.Seconds.ToString() + " seconden";  //seconds
    
                readableTime.Append(values[3]);
            }
            else
                values[3] = string.Empty;
    
    
            return readableTime.ToString();
        }//end SpanToReadableTime
    
    0 讨论(0)
  • 2020-11-22 12:41

    Here is my extension method:

    public static string ToFormattedString(this TimeSpan ts)
    {
        const string separator = ", ";
    
        if (ts.TotalMilliseconds < 1) { return "No time"; }
    
        return string.Join(separator, new string[]
        {
            ts.Days > 0 ? ts.Days + (ts.Days > 1 ? " days" : " day") : null,
            ts.Hours > 0 ? ts.Hours + (ts.Hours > 1 ? " hours" : " hour") : null,
            ts.Minutes > 0 ? ts.Minutes + (ts.Minutes > 1 ? " minutes" : " minute") : null,
            ts.Seconds > 0 ? ts.Seconds + (ts.Seconds > 1 ? " seconds" : " second") : null,
            ts.Milliseconds > 0 ? ts.Milliseconds + (ts.Milliseconds > 1 ? " milliseconds" : " millisecond") : null,
        }.Where(t => t != null));
    }
    

    Example call:

    string time = new TimeSpan(3, 14, 15, 0, 65).ToFormattedString();
    

    Output:

    3 days, 14 hours, 15 minutes, 65 milliseconds
    
    0 讨论(0)
提交回复
热议问题