views:

52

answers:

3

I have a class with a DateTimeOffset property:

public class Sample 
{
    public DateTimeOffset expires { get; set; }
}

and eventually a collection of them:

IEnumerable<Sample> collection;

2 questions:

  1. What is the best way to create a method that returns all the Sample items from the collection where expires is greater than now and is still today (ie before midnight)?

  2. What is the best way to return all Sample items from the collection where expires is in the next 24 hours?

A: 
// greater than now, still today            
collection.Where(d => d.expires.DateTime > DateTime.Now && d.expires.Date == DateTime.Today);

// expires in the next 24 hours
collection.Where(d => d.expires.DateTime > DateTime.Now && d.expires.DateTime < DateTime.Now.AddHours(24));
danijels
Thanks for the answer, but this does not work when d.expires is a DateTimeOffset as mentioned in the question.
Chris
Ok, try again, I've adjusted the queries to offset type. Sorry I missed that
danijels
A: 
var list1 = 
    collection.Where
        (c => c.expires.DateTime > DateTime.Now && 
              c.expires.DateTime < DateTime.Today.AddDays(1));

var list2 = 
    collection.Where
        (c => c.expires.DateTime >= DateTime.Now && 
              c.expires.DateTime <= DateTime.Now.AddHours(24));
code4life
Thanks for the answer, but this does not work when c.expires is a DateTimeOffset as mentioned in the question
Chris
A: 

It's a god practice to "cache" the calculated values for performance, otherwise it would be calculated in each loop(as Where does a loop internally):

DateTime tomorrow = DateTime.Today.AddDays(1);
DateTime now = DateTime.Now;
DateTime next24hrs = now.AddHours(24);
IEnumerable<Sample> next24HoursSamples = collection.Where(sample=>sample.expires>now && sample.expires<next24hrs).ToList();
IEnumerable<Sample> sameDaySamples = next24HoursSamples.Where(sample=>sample.expires>=now && sample.expires<tomorrow).ToList();

Notice that the sameDay list is retrived from the already filtered list(same day is a subset of the next 24 hours),so there are less items to filter on.

EDIT: I updted the code to use an immediate query execution model, as @danijels warns about deferred execution.

jaraics
I don't think this is very wise. As Linq defers execution, calculating DateTime values and passing them to Linq means that in theory, by the time the execution is actually performed, the values might have changed. It is enough to consider this code running seconds before midnight and some operation in between allowing for new day to start, and everything is wrong. Not to mention if this was meant to be in a compiled linq query.
danijels
That might be true theoretically, but practically the deferred execution could also runover midnight and screw all up. It's only a good practice, it's not a rule.
jaraics