Skip to content

Commit

Permalink
fix time span humanization precision skipping
Browse files Browse the repository at this point in the history
  • Loading branch information
mexx committed Oct 21, 2014
1 parent 9770336 commit add3952
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 25 deletions.
24 changes: 15 additions & 9 deletions src/Humanizer.Tests/TimeSpanHumanizeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,36 @@ public void Milliseconds(int ms, string expected)
[InlineData(10, 2, "10 milliseconds")]
[InlineData(1400, 2, "1 second, 400 milliseconds")]
[InlineData(2500, 2, "2 seconds, 500 milliseconds")]
[InlineData(60001, 1, "1 minute")]
[InlineData(60001, 2, "1 minute")]
[InlineData(60001, 3, "1 minute, 1 millisecond")]
[InlineData(120000, 2, "2 minutes")]
[InlineData(62000, 2, "1 minute, 2 seconds")]
[InlineData(62020, 2, "1 minute, 2 seconds")]
[InlineData(62020, 3, "1 minute, 2 seconds, 20 milliseconds")]
[InlineData(3600020, 4, "1 hour, 20 milliseconds")]
[InlineData(3600020, 3, "1 hour, 20 milliseconds")]
[InlineData(3600020, 2, "1 hour, 20 milliseconds")]
[InlineData(3600020, 3, "1 hour")]
[InlineData(3600020, 2, "1 hour")]
[InlineData(3600020, 1, "1 hour")]
[InlineData(3603001, 2, "1 hour, 3 seconds")]
[InlineData(3603001, 3, "1 hour, 3 seconds, 1 millisecond")]
[InlineData(3603001, 2, "1 hour")]
[InlineData(3603001, 3, "1 hour, 3 seconds")]
[InlineData(86400000, 3, "1 day")]
[InlineData(86400000, 2, "1 day")]
[InlineData(86400000, 1, "1 day")]
[InlineData(86401000, 1, "1 day")]
[InlineData(86401000, 2, "1 day, 1 second")]
[InlineData(86401200, 2, "1 day, 1 second")]
[InlineData(86401200, 3, "1 day, 1 second, 200 milliseconds")]
[InlineData(86401000, 2, "1 day")]
[InlineData(86401000, 3, "1 day")]
[InlineData(86401000, 4, "1 day, 1 second")]
[InlineData(86401200, 4, "1 day, 1 second")]
[InlineData(86401200, 5, "1 day, 1 second, 200 milliseconds")]
[InlineData(1296000000, 1, "2 weeks")]
[InlineData(1296000000, 2, "2 weeks, 1 day")]
[InlineData(1299600000, 2, "2 weeks, 1 day")]
[InlineData(1299600000, 3, "2 weeks, 1 day, 1 hour")]
[InlineData(1299630020, 3, "2 weeks, 1 day, 1 hour")]
[InlineData(1299630020, 4, "2 weeks, 1 day, 1 hour, 30 seconds")]
[InlineData(1299630020, 5, "2 weeks, 1 day, 1 hour, 30 seconds, 20 milliseconds")]
[InlineData(1299630020, 4, "2 weeks, 1 day, 1 hour")]
[InlineData(1299630020, 5, "2 weeks, 1 day, 1 hour, 30 seconds")]
[InlineData(1299630020, 6, "2 weeks, 1 day, 1 hour, 30 seconds, 20 milliseconds")]
public void TimeSpanWithPrecesion(int milliseconds, int precesion, string expected)
{
var actual = TimeSpan.FromMilliseconds(milliseconds).Humanize(precesion);
Expand Down
60 changes: 44 additions & 16 deletions src/Humanizer/TimeSpanHumanizeExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using Humanizer.Configuration;
using Humanizer.Localisation;
using Humanizer.Localisation.Formatters;

namespace Humanizer
{
Expand All @@ -20,22 +23,47 @@ public static class TimeSpanHumanizeExtensions
/// <returns></returns>
public static string Humanize(this TimeSpan timeSpan, int precision = 1, CultureInfo culture = null)
{
var result = new StringBuilder();
for (int i = 0; i < precision; i++)
{
var timePart = GetTimePart(timeSpan, culture);

if (result.Length > 0)
result.Append(", ");

result.Append(timePart);

timeSpan = TakeOutTheLargestUnit(timeSpan);
if (timeSpan == TimeSpan.Zero)
break;
}

return result.ToString();
return string.Join(", ", GetTimeParts(timeSpan, culture).Take(precision).Where(x => x != null));
}

private static IEnumerable<string> GetTimeParts(TimeSpan timespan, CultureInfo culture)
{
var weeks = timespan.Days / 7;
var daysInWeek = timespan.Days % 7;
var hours = timespan.Hours;
var minutes = timespan.Minutes;
var seconds = timespan.Seconds;
var milliseconds = timespan.Milliseconds;

var outputWeeks = weeks > 0;
var outputDays = outputWeeks || daysInWeek > 0;
var outputHours = outputDays || hours > 0;
var outputMinutes = outputHours || minutes > 0;
var outputSeconds = outputMinutes || seconds > 0;
var outputMilliseconds = outputSeconds || milliseconds > 0;

var formatter = Configurator.GetFormatter(culture);
if (outputWeeks)
yield return GetTimePart(formatter, TimeUnit.Week, weeks);
if (outputDays)
yield return GetTimePart(formatter, TimeUnit.Day, daysInWeek);
if (outputHours)
yield return GetTimePart(formatter, TimeUnit.Hour, hours);
if (outputMinutes)
yield return GetTimePart(formatter, TimeUnit.Minute, minutes);
if (outputSeconds)
yield return GetTimePart(formatter, TimeUnit.Second, seconds);
if (outputMilliseconds)
yield return GetTimePart(formatter, TimeUnit.Millisecond, milliseconds);
else
yield return formatter.TimeSpanHumanize_Zero();
}

private static string GetTimePart(IFormatter formatter, TimeUnit timeUnit, int unit)
{
return unit != 0
? formatter.TimeSpanHumanize(timeUnit, unit)
: null;
}

private static string GetTimePart(TimeSpan timespan, CultureInfo culture)
Expand Down

0 comments on commit add3952

Please sign in to comment.