Custom TimeSpan String Formats

I want to format TimeSpans in C # as follows:

xxx day yyy hours zzz minutes

Conditions:

  • Extra seconds must be truncated

  • day (s) is the largest unit I want. I want 34 days to be displayed as 34 days, not 1 month 4 days, etc.

  • If the time span is less than one day, I do not want part of the day to be displayed. Similarly, if the interval is less than 1 hour, I want to show only part of the min.

Is there a way I can do this using the inline formatting strings or is there no other way than writing my own function?

Edit: Currently, my own function is used for this. This takes TimeSpan in minutes as input (TimeSpan.TotalMinutes) :

 private static string GetTimeStringFromMinutes(double p) { var minutes = (int) p; int hours = minutes / 60; minutes = minutes % 60; int days = hours/24; hours = hours%24; string dayPart = days + " day(s) "; string hoursPart = hours + " hour(s) "; string minutesPart = minutes + " minute(s)"; if (days != 0) return (dayPart + hoursPart + minutesPart); if (hours != 0) return (hoursPart + minutesPart); return (minutesPart); } 
+4
source share
4 answers

TimeSpan does not have formatting options before .NET 4.0 at all, you will have to convert it to DateTime via the Ticks property. Nothing has been removed to close in the DateTime.String (format) formatting options, although you will have to write it yourself.

In .NET 4.0, TimeSpan acquired an override of ToString (format). Custom formatting strings are described here . Your third requirement will need a code.

+6
source

In .NET 3.5 and earlier, you need to write your own function.

.NET 4 added support for formatting TimeSpan , see TimeSpan.ToString(string) for more details.

+5
source

There is no built-in way to fulfill your requirement, at least in .NET 3.5. Here is a class that extends TimeSpan to provide the desired functionality.

 public static class TimeSpanEx { public static string FormattedString(this TimeSpan ts) { int days = (int)ts.TotalDays; int hrs = (int)ts.Hours; int mins = (int)ts.Minutes; StringBuilder sb = new StringBuilder(); if (days > 0) { sb.Append(days.ToString() + (days == 1 ? " day, " : " days, ")); } if (hrs > 0 || days > 0) { sb.Append(hrs.ToString() + (hrs == 1 ? " hour, " : " hours, ")); } sb.Append(mins.ToString() + (mins == 1 ? " min" : " mins")); return sb.ToString(); } } 
+3
source

Unfortunately, there is nothing available in .Net. For myself, I solved the problem this way:

 public static class TimeSpanExtensions { public static string ToDetailedString(this TimeSpan timeSpan) { if (timeSpan == null) throw new ArgumentNullException("timeSpan"); var sb = new StringBuilder(30); var current = timeSpan.ToDaysString(); if (!String.IsNullOrEmpty(current)) sb.Append(current); current = timeSpan.ToHoursString(); if (!String.IsNullOrEmpty(current)) { if (sb.Length > 0) sb.Append(" "); sb.Append(current); } current = timeSpan.ToMinutesString(); if (!String.IsNullOrEmpty(current)) { if (sb.Length > 0) sb.Append(" "); sb.Append(current); } return sb.ToString(); } public static string ToDaysString(this TimeSpan timeSpan) { if (timeSpan == null) throw new ArgumentNullException("timeSpan"); int days = (int)timeSpan.TotalDays; switch (days) { case 0: return String.Empty; case 1: return "1 day"; default: return days + " days"; } } public static string ToHoursString(this TimeSpan timeSpan) { if (timeSpan == null) throw new ArgumentNullException("timeSpan"); switch (timeSpan.Hours) { case 0: return String.Empty; case 1: return "1 hour"; default: return timeSpan.Hours + " hours"; } } public static string ToMinutesString(this TimeSpan timeSpan) { if (timeSpan == null) throw new ArgumentNullException("timeSpan"); switch (timeSpan.Minutes) { case 0: return String.Empty; case 1: return "1 minute"; default: return timeSpan.Minutes + " minutes"; } } } 

This may not be the most elegant solution, and I think some improvements can be made especially in the ToDetailedString() function, but it works absolutely fine.

+2
source

All Articles