Skip to content

Commit

Permalink
feat: add extension to simplify timespan
Browse files Browse the repository at this point in the history
  • Loading branch information
sandre58 committed Jun 21, 2024
1 parent e772c10 commit 5c60b2b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Stéphane ANDRE. All Right Reserved.
// See the LICENSE file in the project root for more information.

using System;
using MyNet.Utilities.Units;
using Xunit;

namespace MyNet.Utilities.UnitTests.Extensions
{
public class TimeSpanExtensionsTests
{
[Theory]
[InlineData(0, 0, 30, 30, TimeUnit.Minute)]
[InlineData(0, 5, 0, 5, TimeUnit.Hour)]
[InlineData(2, 0, 0, 2, TimeUnit.Day)]
[InlineData(30, 0, 0, 1, TimeUnit.Month)]
[InlineData(365, 0, 0, 1, TimeUnit.Year)]
[InlineData(0, 0, 0, 0, TimeUnit.Millisecond)]
[InlineData(14, 0, 0, 2, TimeUnit.Week)]
[InlineData(60, 0, 0, 2, TimeUnit.Month)]
[InlineData(730, 0, 0, 2, TimeUnit.Year)]
[InlineData(22, 0, 0, 22, TimeUnit.Day)]
[InlineData(0, 1, 23, 83, TimeUnit.Minute)]
[InlineData(1, 0, 42, 1482, TimeUnit.Minute)]
public void Simplify_ShouldReturnExpectedResult(int days, int hours, int minutes, int expectedValue, TimeUnit expectedUnit)
{
var (value, unit) = new TimeSpan(days, hours, minutes, 0).Simplify();

Assert.Equal(expectedValue, value);
Assert.Equal(expectedUnit, unit);
}
}
}
23 changes: 23 additions & 0 deletions src/MyNet.Utilities/Extensions/TimeSpanExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using MyNet.Utilities.DateTimes;
using MyNet.Utilities.Units;

Expand Down Expand Up @@ -172,5 +173,27 @@ public static TimeSpan Round(this TimeSpan timeSpan, RoundTo rt)
TimeUnit.Year => new TimeSpan((int)Math.Round(value * DaysInAYear), 0, 0, 0, 0),
_ => new TimeSpan(),
};

public static (int value, TimeUnit unit) Simplify(this TimeSpan time)
{
var dictionary = new Dictionary<TimeUnit, (Func<TimeSpan, bool> checkValue, Func<TimeSpan, double> getTotal)>
{
{ TimeUnit.Second, (new Func<TimeSpan, bool>(x => x.Seconds != 0), new Func<TimeSpan, double>(x => x.TotalSeconds)) },
{ TimeUnit.Minute, (new Func<TimeSpan, bool>(x => x.Minutes != 0), new Func<TimeSpan, double>(x => x.TotalMinutes)) },
{ TimeUnit.Hour, (new Func<TimeSpan, bool>(x => x.Hours != 0), new Func<TimeSpan, double>(x => x.TotalHours)) },
{ TimeUnit.Year, (new Func<TimeSpan, bool>(x => x.Days > 0 && x.Days % (int)DaysInAYear == 0), new Func<TimeSpan, double>(x => x.TotalDays / (int)DaysInAYear)) },
{ TimeUnit.Month, (new Func<TimeSpan, bool>(x => x.Days > 0 && x.Days % (int)DaysInAMonth == 0), new Func<TimeSpan, double>(x => x.TotalDays / (int)DaysInAMonth)) },
{ TimeUnit.Week, (new Func<TimeSpan, bool>(x => x.Days > 0 && x.Days % DaysInAWeek == 0), new Func<TimeSpan, double>(x => x.TotalDays / DaysInAWeek)) },
{ TimeUnit.Day, (new Func<TimeSpan, bool>(x => x.Days != 0), new Func<TimeSpan, double>(x => x.TotalDays)) },
};

foreach (var (unit, value) in dictionary)
{
if (value.checkValue.Invoke(time))
return ((int)value.getTotal.Invoke(time), unit);
}

return (0, TimeUnit.Millisecond);
}
}
}

0 comments on commit 5c60b2b

Please sign in to comment.