cullimorer
cullimorer

Reputation: 755

Calculating hourly breakdown of minutes in each hour for a period of time

I am trying to get a breakdown of minutes in each hour across a period of time. For example, lets say I have two DateTimes like so:

DateTime onTime = new DateTime(2019, 11, 6, 6, 30, 0);
DateTime offTime = new DateTime(2019, 11, 6, 10, 45, 0);

So there are two DateTimes representing:

"2019-11-06 06:30:00"
"2019-11-06 10:45:00"

What I am trying to achieve is an hourly breakdown of minutes in each hour for the given period. I would expect that to look something like:

int 6 = 30; // Hour 6 = 30 minutes
int 7 = 60; // Hour 7 = 60 minutes
int 8 = 60; // Hour 8 = 60 minutes
int 9 = 60; // Hour 8 = 60 minutes
int 10 = 45; // Hour 10 = 45 minutes

I can work out whether to try and use LINQ or just a self referencing iterative function for the desired affect.

Upvotes: 1

Views: 126

Answers (1)

Corentin Pane
Corentin Pane

Reputation: 4943

The only interesting values are the first component and the last component, all others will be 60 no matter what (if there is at least a one hour gap). This is why I would go with the following code:

public static IEnumerable<int> GetBreakdown(DateTime onTime, DateTime offTime) {
    if (offTime < onTime) {
        throw new ArgumentException();
    }

    // Case where the two times start at the same hour
    if (onTime.Hour == offTime.Hour) {
        yield return offTime.Minute - onTime.Minute;
        yield break;
    }

    // Nominal case
    yield return 60 - onTime.Minute;
    for (int i = onTime.Hour + 1; i < offTime.Hour; i++) {
        yield return 60;
    }
    if (offTime.Minute != 0) {
        yield return offTime.Minute;
    }
}

that you could use this way:

DateTime onTime = new DateTime(2019, 11, 6, 6, 30, 0);
DateTime offTime = new DateTime(2019, 11, 6, 10, 45, 0);
foreach (var value in GetBreakdown(onTime, offTime)) {
    Console.WriteLine(value);
}
// Prints:
// 30
// 60
// 60
// 60
// 45

Note that it assumes that both are on the same day, it doesn't consider the Date component of the inputs. From here you can easily change the return type from IEnumerable<int> to IEnumerable<(int, int)> and make the changes to return the hour component in each yield.

Upvotes: 5

Related Questions