C# get whole hour values between 2 datetime objects

I am trying to get the affected hours between 2 datetime and all i found was a python solution.

For example 'start' is 09:30 and 'end' is 14:00 (same day). The values I'd like returned are

[9:00, 10:00, 11:00, 12:00, 13:00, 14:00]

Python get whole hour values between 2 datetime objects

I can't seem to find any equivalent to C#.

Upvotes: 3

Views: 4838

Answers (9)

Tim Schmelter
Tim Schmelter

Reputation: 460018

So you want a list of all hours between both dates? You can use this query:

TimeSpan ts =  dt2 - dt1;
IEnumerable<int> hoursBetween = Enumerable.Range(0, (int)ts.TotalHours)
    .Select(i => dt1.AddHours(i).Hour);

Sample dates:

DateTime dt1 = new DateTime(2013, 07, 08, 15, 50, 00);
DateTime dt2 = new DateTime(2013, 07, 10, 19, 30, 00);
TimeSpan ts =  dt2 - dt1;

IEnumerable<int> hoursBetween = Enumerable.Range(0, (int)ts.TotalHours)
    .Select(i => dt1.AddHours(i).Hour);

foreach (int hour in hoursBetween)
    Console.WriteLine(hour);

Output:

15
16
17
18
19
20
21
22
23
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Upvotes: 8

Ron.B.I
Ron.B.I

Reputation: 2766

The following will return the total hours between the 2 DateTime objects:

(datevalue1 - datevalue2).TotalHours

And for a custom behavior,such as displaying a list of hours, use a simple custom method on that Timespan created to get a list of hours in your desired format.

Code suggestion of the top of my head:

public List<String> GenerateHours(DateTime t1,DateTime t2){
    if ((t2-t1).TotalHours >24)){
        //decide what to do.
        return null;
    }else{
        var currentHour = t2.Hour;
        var list = new List<String>();
        for (int i=0;i<(t2-t1).TotalHours;i++){
            if (currentHour<10){
                list.Add("0"+currentHour+":00");
            }else if (currentHour>=10){
                list.Add(currentHour+":00");
            }
            currentHour= (currentHour+1)%24;
        }
        return list;
    }
}

Upvotes: 3

aquinas
aquinas

Reputation: 23786

TimeSpan ts = DateTime1 - DateTime2;
double totalHours = ts.TotalHours;

From MSDN: "Gets the value of the current TimeSpan structure expressed in whole and fractional hours."

EDIT: ok, now I see what you're asking for. How about this:

var d1 = DateTime.Today.AddHours(9.5);
var d2 = DateTime.Today.AddHours(14);

var first = new DateTime(d1.Year, d1.Month, d1.Day, d1.Minute == 0 ? d1.Hour : d1.Hour + 1, 0, 0);
var second = new DateTime(d2.Year, d2.Month, d2.Day, d2.Minute == 0 ? d2.Hour : d2.Hour + 1, 0, 0);

TimeSpan ts = second - first;

//returns DateTimes affected. I.e., Today at, [10:00, 11:00, 12:00, 13:00, 14:00]
IEnumerable<DateTime> dates = Enumerable.Range(0, (int)ts.TotalHours + 1).Select(hour => first.AddHours(hour));

//Or, if you just want the HOURs
//returns just ints: i.e., DateTimes 10,11,12,13,14
IEnumerable<int> hours = Enumerable.Range(0, (int)ts.TotalHours + 1).Select(hour => first.AddHours(hour).Hour);

The first method is needed if you actually have dates that span days. If you DON'T, then the second method that just returns the hours would work fine.

Upvotes: 2

Sebastian Negraszus
Sebastian Negraszus

Reputation: 12195

public IEnumerable<DateTime> GetHoursBetween(DateTime start, DateTime end)
{
    DateTime first = start.Date.AddHours(start.Hour);
    for (DateTime dateTime = first; dateTime <= end; dateTime = dateTime.AddHours(1))
    {
        yield return dateTime;
    }
}

Upvotes: 2

keyboardP
keyboardP

Reputation: 69362

You can use a For loop

List<int> allHoursBetween = new List<int>();

for (DateTime d = myStartDate; d <= myEndDate; d = d.AddHours(1))
     allHoursBetween.Add(d.Hour);

Upvotes: 0

Tim
Tim

Reputation: 15227

Maybe something like this would work?

    public static List<DateTime> GetAffectedHours(DateTime start, DateTime end)
    {
        List<DateTime> result = new List<DateTime>();

        // Strip start of its minutes/seconds/etc
        DateTime initial = new DateTime(start.Year, start.Month, start.Day, start.Hour, 0, 0);

        // Go ahead and get the next hour
        DateTime iterator = initial.AddHours(1.0);

        // if it is still before the end
        while (iterator < end)
        {
            // add it to the results list
            result.Add(iterator);

            // and get the next hour
            iterator = iterator.AddHours(1.0);
        }

        return result;
    }

Upvotes: 0

Maarten
Maarten

Reputation: 22945

This should do the trick. Tested in LinqPad.

var startDate = new DateTime(2013, 8, 7, 9, 30, 0);
var endDate = new DateTime(2013, 8, 7, 14, 0, 0);

List<string> times = new List<string>();

var currentTime = startDate;
if (currentTime.Minute != 0 || currentTime.Second != 0) {
    // Get next hour
    currentTime = currentTime.AddHours(1).AddMinutes(currentTime.Minute * -1);
}

while (currentTime <= endDate) {
    times.Add(string.Format("{0:00}:00", currentTime.Hour));
    currentTime = currentTime.AddHours(1);
}

Upvotes: 1

Icarus
Icarus

Reputation: 63956

Simply subtract them and get the total of hours from the result. Something like this:

var totalHours = (dateTime1 - dateTime2).TotalHours;

Upvotes: 0

Tim S.
Tim S.

Reputation: 56536

(int)Math.Abs((date1 - date2).TotalHours)

Upvotes: 0

Related Questions