I have TimeSpan
object that tracks calculation times. This TimeSpan
can range from seconds to days. I currently have a quite verbose method in place to give me a string from the TimeSpan
that represents the TimeSpan
in a long form; for example:
3 Days 13 Hours 1 Minute 52 Seconds
When the TimeSpan
is less than 1
second, I display the Milliseconds
property instead. The code for this is simplistic but is quite verbose as I stated above. Is there a concise way to achieve this similar to DateTime.Now.ToString("ddMMyyyy hhmmssffff")
? Below is my current code:
public static string GetLongTime(TimeSpan t) {
string result = string.Empty;
if (t.Days > 0) {
if (t.Days == 1) result = "1 Day";
else result = $"{t.Days} Days";
} else if (t.TotalMilliseconds < 1000) {
if (t.Milliseconds > 0)
result = $"{t.Milliseconds}ms";
} else {
if (t.Hours > 0) {
if (t.Hours == 1) result += "1 Hour ";
else result += $"{t.Hours} Hours ";
}
if (t.Minutes > 0) {
if (t.Minutes == 1) result += "1 Minute ";
else result += $"{t.Minutes} Minutes ";
}
if (t.Seconds > 0) {
if (t.Seconds == 1) result += "1 Second ";
else result += $"{t.Seconds } Seconds ";
}
}
return result;
}
Just as with DateTime
, the TimeSpan
object has a custom format list; however, their example list displays strings with the good ol' fashioned (s)
appendage:
TimeSpan duration = new TimeSpan(1, 12, 23, 62);
Console.WriteLine("Time of Travel: {0:%d} day(s)", duration);
Console.WriteLine("Time of Travel: {0:dd\\.hh\\:mm\\:ss} days", duration);
Time of Travel: 1 day(s)
Time of Travel: 01.12:24:02 days
This isn't really what I'm looking for. I've also looked into some related posts here on StackOverflow, and as one user pointed out in a comment, they are good resources. Overall, these aren't the solutions I'm looking for either as I am mostly in high hopes of something incredibly concise such as:
return t.ToString("d Day?s");
Granted the above is just pseudo and wouldn't actually do more than:
3 Day?s
Some of the related posts have promise to refactor my code; for example, this post that recommends the conditional assignment operator:
string result = string.Empty;
if (t.Days > 0)
return $"{t.Days} {(t.Days > 1 ? "Days " : "Day ")}";
else if (t.TotalMilliseconds < 1000) {
if (t.Milliseconds > 0)
return $"{t.Milliseconds}ms";
} else {
if (t.Hours > 0)
result += $"{t.Hours} {(t.Hours > 1 ? "Hours " : "Hour ")}";
if (t.Minutes > 0)
result += $"{t.Minutes} {(t.Minutes > 1 ? "Minutes " : "Minute ")}";
if (t.Seconds > 0)
result += $"{t.Seconds} {(t.Seconds > 1 ? "Seconds " : "Second ")}";
}
return result;
Though this shortens the code, it doesn't exactly make it look the cleanest either (especially to new developers). Which is also in line with this post that recommends using a SortedList
of the proper formats; however, I agree with the OP on that post; Your code does take some time to follow. That's the only thing I'm not in love with..
Is there a way to achieve conditional pluralization within the format string; or, is there a more simplistic and concise approach compared to what I have above?