Reputation: 755
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
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