Khan
Khan

Reputation: 18162

Get list of (floored) hours between two DateTimes

I wrote a function to inclusively give me a list of hours that fall between two DateTime's.

But in the end it doesn't really look very easy to read and it makes me want to unit test it even though the project I'm working on doesn't unit test at all.

So my question is, is there a more legible and or efficient way to write this?:

Code:

private List<DateTime> GetHoursForEvent(DateTime start, DateTime end)
{
    var hours = new List<DateTime>();

    DateTime startFloor = Convert.ToDateTime(start.ToString("MM/dd/yyyy HH:00:00"));
    DateTime endFloor = Convert.ToDateTime(end.ToString("MM/dd/yyyy HH:00:00"));

    for (double dblDate = startFloor.ToOADate(); 
         dblDate <= endFloor.ToOADate(); 
         dblDate += (1.0 / 24.0))
    {
        hours.Add(DateTime.FromOADate(dblDate));
    }

    return hours;
}

Input:

DateTime start = Convert.ToDateTime("2012-04-01 04:22:00");
DateTime end   = Convert.ToDateTime("2012-04-02 00:05:00");

Result:

2012-04-01 04:00:00
2012-04-01 05:00:00
2012-04-01 06:00:00
2012-04-01 07:00:00
2012-04-01 08:00:00
2012-04-01 09:00:00
2012-04-01 10:00:00
2012-04-01 11:00:00
2012-04-01 12:00:00
2012-04-01 13:00:00
2012-04-01 14:00:00
2012-04-01 15:00:00
2012-04-01 16:00:00
2012-04-01 17:00:00
2012-04-01 18:00:00
2012-04-01 19:00:00
2012-04-01 20:00:00
2012-04-01 21:00:00
2012-04-01 22:00:00
2012-04-01 23:00:00
2012-04-02 00:00:00

I get the feeling i'm reinventing the wheel.

Upvotes: 4

Views: 886

Answers (2)

Likurg
Likurg

Reputation: 2760

Try use this code

private List<DateTime> GetHoursForEvent(DateTime start, DateTime end)
    {
        List<DateTime> hours = new List<DateTime>();
        while (start < end)
        {
            hours.Add(start);
            start = start.AddHours(1);
        }
        return hours;
    }

Upvotes: 1

StriplingWarrior
StriplingWarrior

Reputation: 156708

Yeah, something like this should work better for you:

private List<DateTime> GetHoursForEvent(DateTime start, DateTime end)
{
    var hours = new List<DateTime>();
    var current = new DateTime(start.Year, start.Month, start.Day, start.Hour, 0, 0);
    while(current <= end)
    {
        hours.Add(current);
        current = current.AddHours(1);
    }
    return hours;
}

You may even want to make this into a streaming method, unless there's a specific reason you need to return a List:

private IEnumerable<DateTime> GetHoursForEvent(DateTime start, DateTime end)
{
    var current = new DateTime(start.Year, start.Month, start.Day, start.Hour, 0, 0);
    while(current <= end)
    {
        yield return current;
        current = current.AddHours(1);
    }
}

Upvotes: 9

Related Questions