Filter by time range in list of DateTime objects

I have a list of DateTime objects.

I need to take from this list only those objects that have time part of the date between '00:00:01' and '12:00:00'.

How can I query this list?

If I would make a SQL Query I would do something this way

SELECT TspCreated,
    CASE 
        WHEN cast(TspCreated as time) > '00:00:00' AND 
             cast(TspCreated as time) <= '12:00:00' 
             THEN '00 - 12'
        WHEN cast(TspCreated as time) > '12:00:00' AND 
             cast(TspCreated as time) <= '18:00:00' 
             THEN '12 - 18'
        WHEN cast(TspCreated as time) > '18:00:00' AND 
             cast(TspCreated as time) <= '23:59:59' 
             THEN '18 - 24'
    END AS TimeFrame
FROM MyTable

EDIT:

Thanks to Jon Skeet answer I had the way to use Timespan objects as the boundaries for my query. Unfortunately, in my case that answer is not applicable because Linq-to-Entities does not support usage of TimeOfDay property. I have ended up with usage of Entity Framework Canonical Functions:

TimeSpan ts_0 = new TimeSpan( 0, 0, 0 );
TimeSpan ts_12 = new TimeSpan( 12, 0, 0 );
int NumOfIssues = ctx.MyEntitySet.Where( x => 
                      DbFunctions.CreateTime( x.TspUsed.Hour, x.TspUsed.Minute, x.TspUsed.Second ) >= ts_0 &&
                      DbFunctions.CreateTime( x.TspUsed.Hour, x.TspUsed.Minute, x.TspUsed.Second ) < ts_12).Count();
Jon Skeet
people
quotationmark

It seems to me that all you need is the DateTime.TimeOfDay property. I would then recommend changing your conditions slightly if you're able to, so that the lower bound is inclusive and the upper bound is exclusive, e.g.

var time = dateTime.TimeOfDay;
if (time.Hours < 12)
{
    Console.WriteLine("Morning");
}
else if (time.Hours < 18)
{
    Console.WriteLine("Afternoon");
}
else
{
    Console.WriteLine("Evening");
}

As an example of why that's handy, your current classification excludes midnight entirely along with anything between 11:59:59pm and midnight, e.g. 11:59:59.999.

Or you could create appropriate TimeSpan values for the boundaries and use the regular <, <= etc operators. For example:

TimeSpan noon = new TimeSpan(12, 0, 0);
TimeSpan sixPm = new TimeSpan(18, 0, 0);
TimeSpan time = dateTime.TimeOfDay;
if (time < noon)
{
    ...
}
else if (time < sixPm)
{
    ...
}
else
{
    ...
}

Note that with both approaches, I'm only checking one condition per if statement, because I basically move through the day, from midnight onwards. If you just wanted to check one band in the middle, you could say:

if (noon <= time && time < sixPm)

As a slight aside, I've never liked that TimeOfDay returns a TimeSpan - an elapsed period of time isn't the same as a time of day. If you feel the same and you're doing any significant amount of date/time work, you might want to consider looking at my Noda Time project, which has a lot more types to represent various aspects of dates and times.

people

See more on this question at Stackoverflow