snippetcsharpMinor
convert timespan to readable text
Viewed 0 times
converttextreadabletimespan
Problem
I'm trying to convert TimeSpan object to text that can be read like a sentence.
e.g.
Some more samples for conversion are in the 'TestCases' object under 'TimeSpanPrettyFormatterTests' class.
Is there any better way to do it than the one i suggested here?
Thanks
```
using System;
using JetBrains.Annotations;
using NUnit.Framework;
namespace Client.Tests
{
[TestFixture]
public class TimeSpanPrettyFormatterTests
{
[UsedImplicitly]
static object[] TestCases =
{
new object[] { new TimeSpan(0, 0, 0, 0), string.Empty },
new object[] { new TimeSpan(1, 0, 0, 0), "A day" },
new object[] { new TimeSpan(2, 0, 0, 0), "2 days" },
new object[] { new TimeSpan(0, 1, 0, 0), "An hour" },
new object[] { new TimeSpan(1, 1, 0, 0), "A day and an hour" },
new object[] { new TimeSpan(2, 1, 0, 0), "2 days and an hour" },
new object[] { new TimeSpan(0, 2, 0, 0), "2 hours" },
new object[] { new TimeSpan(1, 2, 0, 0), "A day and 2 hours" },
new object[] { new TimeSpan(2, 2, 0, 0), "2 days and 2 hours" },
new object[] { new TimeSpan(0, 0, 1, 0), "A minute" },
new object[] { new TimeSpan(1, 0, 1, 0), "A day and a minute" },
new object[] { new TimeSpan(2, 0, 1, 0), "2 days and a minute" },
new object[] { new TimeSpan(0, 1, 1, 0), "An hour and a minute" },
new object[] { new TimeSpan(1, 1, 1, 0), "A day, an hour and a minute" },
new object[] { new TimeSpan(2, 1, 1, 0), "2 days, an hour and a minute" },
new object[] { new TimeSpan(0, 2, 1, 0), "2 hours and a minute" },
new object[] { new TimeSpan(1, 2, 1, 0), "A day, 2 hours and a minute" },
new object[] { new TimeSpan(2, 2, 1, 0), "2 days, 2 hours and a minute" },
new object[] { ne
e.g.
TimeSpan(2, 1, 0, 0) --> "2 days and an hour"
TimeSpan(1, 2, 1, 0) --> "A day, 2 hours and a minute"Some more samples for conversion are in the 'TestCases' object under 'TimeSpanPrettyFormatterTests' class.
Is there any better way to do it than the one i suggested here?
Thanks
```
using System;
using JetBrains.Annotations;
using NUnit.Framework;
namespace Client.Tests
{
[TestFixture]
public class TimeSpanPrettyFormatterTests
{
[UsedImplicitly]
static object[] TestCases =
{
new object[] { new TimeSpan(0, 0, 0, 0), string.Empty },
new object[] { new TimeSpan(1, 0, 0, 0), "A day" },
new object[] { new TimeSpan(2, 0, 0, 0), "2 days" },
new object[] { new TimeSpan(0, 1, 0, 0), "An hour" },
new object[] { new TimeSpan(1, 1, 0, 0), "A day and an hour" },
new object[] { new TimeSpan(2, 1, 0, 0), "2 days and an hour" },
new object[] { new TimeSpan(0, 2, 0, 0), "2 hours" },
new object[] { new TimeSpan(1, 2, 0, 0), "A day and 2 hours" },
new object[] { new TimeSpan(2, 2, 0, 0), "2 days and 2 hours" },
new object[] { new TimeSpan(0, 0, 1, 0), "A minute" },
new object[] { new TimeSpan(1, 0, 1, 0), "A day and a minute" },
new object[] { new TimeSpan(2, 0, 1, 0), "2 days and a minute" },
new object[] { new TimeSpan(0, 1, 1, 0), "An hour and a minute" },
new object[] { new TimeSpan(1, 1, 1, 0), "A day, an hour and a minute" },
new object[] { new TimeSpan(2, 1, 1, 0), "2 days, an hour and a minute" },
new object[] { new TimeSpan(0, 2, 1, 0), "2 hours and a minute" },
new object[] { new TimeSpan(1, 2, 1, 0), "A day, 2 hours and a minute" },
new object[] { new TimeSpan(2, 2, 1, 0), "2 days, 2 hours and a minute" },
new object[] { ne
Solution
ToPrettyFormat method can definitely be improved. Instead writing the conditional statement for all possible permutations of HasDays, HasHours and HasMinutes it's better to step back and define rules for resulting string:- string may consist of 3 parts (days, hours and minutes)
- if there is 0 or one non-empty part - it is a final result
- if there are 2 non-empty parts - there should be "and" between them
- if there are 3 non-empty parts - first 2 should be separated by comma + "and" before last part. Note that we can actually generalize last two rules for N parts (months, weeks, etc) - instead of "3" we can say combine first N-1 parts with comma and add last one with "and"
As a result you can get a bit simplified code:
public static string ToPrettyFormat(this TimeSpan timeSpan)
{
var dayParts = new[] { GetDays(timeSpan), GetHours(timeSpan), GetMinutes(timeSpan) }
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
var numberOfParts = dayParts.Length;
string result;
if (numberOfParts < 2)
result = dayParts.FirstOrDefault() ?? string.Empty;
else
result = string.Join(", ", dayParts, 0, numberOfParts - 1) + " and " + dayParts[numberOfParts - 1];
return result.UppercaseFirst();
}Code Snippets
public static string ToPrettyFormat(this TimeSpan timeSpan)
{
var dayParts = new[] { GetDays(timeSpan), GetHours(timeSpan), GetMinutes(timeSpan) }
.Where(s => !string.IsNullOrEmpty(s))
.ToArray();
var numberOfParts = dayParts.Length;
string result;
if (numberOfParts < 2)
result = dayParts.FirstOrDefault() ?? string.Empty;
else
result = string.Join(", ", dayParts, 0, numberOfParts - 1) + " and " + dayParts[numberOfParts - 1];
return result.UppercaseFirst();
}Context
StackExchange Code Review Q#24995, answer score: 6
Revisions (0)
No revisions yet.