Search code examples
c#linqextension-methods

Sum TimeSpan by extension method simplification


I found here this extension method

/// <summary>
/// Calculates the sum of the given timeSpans.
/// </summary>
public static TimeSpan Sum(this IEnumerable<TimeSpan> timeSpans)
{
    TimeSpan sumTillNowTimeSpan = TimeSpan.Zero;

    foreach (TimeSpan timeSpan in timeSpans)
    {
        sumTillNowTimeSpan += timeSpan;
    }
    return sumTillNowTimeSpan;           
}

usage:

List<TimeSpan> timeSpans = new List<TimeSpan>();
timeSpans.Add(TimeSpan.FromHours(1));
timeSpans.Add(TimeSpan.FromHours(2));
timeSpans.Add(TimeSpan.FromHours(3));
TimeSpan sum = timeSpans.Sum();// will be 06:00

Question:

Is this extension useful or could it be also be solved with one line linq like

TimeSpan sum = timeSpans.Sum(); //Linq.Sum() - this doesn't compile

I would expect this to compile since Sum() does internal += all values - the curious about his is that intellisense of Visual Studio suggests me to use Sum() and there is a existing overload but it doesn't compile.


Solution

  • So the following doesn't compile...

    List<TimeSpan> timeSpans = new List<TimeSpan>();
    timeSpans.Add(TimeSpan.FromHours(1));
    timeSpans.Add(TimeSpan.FromHours(2));
    timeSpans.Add(TimeSpan.FromHours(3));
    TimeSpan sum = timeSpans.Sum();// will be 06:00
    

    An alternative to the extension method supplied would be ...

    TimeSpan sum = TimeSpan.FromMilliseconds(timeSpans.Sum(t => t.TotalMilliseconds));
    

    EDIT: As pointed out by TheGeneral better to use the Ticks long property to avoid rounding errors if nanoseconds are a concern...

    TimeSpan sum = TimeSpan.FromTicks(timeSpans.Sum(t => t.Ticks));
    

    Although I think I actually prefer kurakura88's answer as it uses TimeSpan's Add method which should be more reliable than any other method you could use to Add TimeSpans