Date range falling between two dates in a LINQ query - c#

I'm trying to write a select query which returns records where the input date range falls between two date fields in a LINQ query.
My inputs are:
date1 - start date
date2 - end date
My database fields are
AppointmentStart
AppointmentEnd
Additionally, I'd also like to ensure that an input of 14:00 - 15:00 doesn't return a value for 15:00-16:00.
return (from t1 in db.Appointments where (t1.AppointmentStart <= date2 && (t1.AppointmentEnd) >= date1)
If anybody can assist me with this, I'd appreciate it.

I'm not 100% clear on your requirements. In your opening line you asked for records "where the input date range falls between two date fields", but in the "Additionally" line you imply that you don't want to return records where the start date of the appointment doesn't equal the end date of your input. I take these to be two different requirements, so I'll give you two different queries.
The first query is:
from t1 in db.Appointments
where date1 >= t1.AppointmentStart
where date2 <= t1.AppointmentEnd
select t1;
The second query is:
from t1 in db.Appointments
where date2 > t1.AppointmentStart
where date1 < t1.AppointmentEnd
select t1;
The first query returns records that "contain" the input dates.
The second query returns records that "overlap" the input dates.
I think it makes more sense that you want the overlap query and this one will meet your "14:00 - 15:00 doesn't return a value for 15:00-16:00" requirement.
Let me know if I made a mistake understanding your requirements and need to make any changes.

It looks backwards to me.
if the following is true:
Date1 = start
Date2 = end
then i would think startdate after or equal to appointmentstart and enddate before or equal to appointmentend or:
return (from t1 in db.Appointments where (date1 >= t1.AppointmentStart && date2 <= t1.AppointmentEnd))
i also changed the parens because they didn't make sense to me (seemed like one was missing)

Related

Search between two date not return result using LINQ WPF C#

Goal:
Searching between two selected date by datepickers.
Inserted dates format :
DateTime.Now()
result is: 2/23/2021 5:18:04 PM
Linq query :
var list = from d in ctx.SellInvoices
where d.Date >= dtpStartDate.SelectedDate.Value
&& d.Date <= dtpEndDate.SelectedDate.Value
select d;
Problem :
if dtpEndDate selected date is tommorow (2/24/2021) it returned result, but if i select today not returned any thing. what is problem here?
Addition:
if saved date as DateTime.Today() result is 2/23/2021 12:00:00 AM and search query returned good but for 12:00:01 AM should selecting one day later. Here I don't want to save with DateTime.Today().
If you have set dtpEndDate as just 2/23/2021 (today) it will actually be 2/23/2021 00:00:00
So when you compare d.Date <= dtpEndDate.SelectedDate.Value
It will be 2/23/2021 5:18:04 PM <= 2/23/2021 00:00:00.

How to compare just month and day from a datetime object

In my C# program I have run into an obstacle where I have a table that stores date ranges (columns are date range ID (int), begin date (DateTime) and end date (DateTime). I want to query the table and get back rows that only fall within a specific date range. I cannot use datetime.date since that includes the year.
So for example, I want to query the table and get all date ranges that fall between 01-01 and 5-31.
I have tried using the following lambda to query the table, but my result set is empty.
List<DateRanges> tempDateRangeList = dataContext
.DateRanges
.Where(r=>r.BeginDate.Month <= startDate.Month
&& r.EndDate.Month >= finishDate.Month)
.ToList();
tempDateRangeList = tempDateRangeList.Where(r=>r.BeginDate.Day <= startDate.Day
&& r.EndDate.Day >= finishDate.Day)
.ToList();
Does anyone have any suggestions on how I could accomplish this?
Edit:
Examples of BeginDate and EndDate would be a list such as follows:
BeginDate 1/1/2016, 5/25/2016, 9/11/2016
EndDates 5/24/2016, 9/10/2016, 12/31/2016
Filter date would be:
startDate = 12/8
finishDate = 12/12
Expected result:
Begin Date of 9/11
End date of 12/31
There are two cases in your condition - month equal to boundary month, in which case you must test day number, and a different month, in which you ignore day. Hence the query:
List<DateRanges> tempDateRangeList =
dataContext.DateRanges.Where(r =>
((r.BeginDate.Month < startDate.Month) ||
(r.BeginDate.Month == startDate.Month && r.BeginDate.Day <= startDate.Day)) &&
((r.EndDate.Month > finishDate.Month) ||
(r.EndDate.Month == finishDate.Month) && r.EndDate.Day >= finsihDate.Day))
.ToList();
Condition is ugly and very hard to follow but covers all cases. This query returns all records which define date ranges that completely fall under the boundary dates.
If you wish to find records that are just overlapping (completely or partially) with the filtering range, then the query would be:
List<DateRanges> tempDateRangeList =
dataContext.DateRanges.Where(r =>
((r.BeginDate.Month < endDate.Month) ||
(r.BeginDate.Month == endDate.Month && r.BeginDate.Day <= endDate.Day)) &&
((r.EndDate.Month > startDate.Month) ||
(r.EndDate.Month == startDate.Month) && r.EndDate.Day >= startDate.Day))
.ToList();
This condition may bend your mind, but it works fine.
If a lambda expression isn't compulsory, I've used linq queries (because it was the first solution i've thought).
var validRanges = from range in ranges
where range.BeginDate.CompareTo(startDate) <= 0
where range.EndDate.CompareTo(endDate) >= 0
select range;
Using CompareTo is the easiest way to compare two DateTime struct.
I invite you to take a look here for a complete description of the method.
Edit
If you aren't interested in hours of your dates, but only in Day and Month, you should use range.BeginDate.Date.CompareTo(startDate.Date) and range.EndDate.Date.CompareTo(endDate.Date)

multiple date range and check if it is sequential. c# MVC

We have this project and one of the business requirement is it allows the client to input a multiple date range and check the individual dates if it is sequential/continuous or not to the others.
eq.
INPUT
startdate - enddate
10/24/2016 - 10/24/2016
10/26/2016 - 10/28/2016
OUTPUT
10/24/2016 - 10/24/2016 - NOT SEQUENTIAL
10/26/2016 - 10/26/2016 - SEQUENTIAL
10/27/2016 - 10/27/2016 - SEQUENTIAL
10/28/2016 - 10/28/2016 - SEQUENTIAL
For now I am playing around this solution
Check if date range is sequential in c#?
but i hope we i can find a better solution on how to properly do it.
Thank you and have a good day!
If by "sequential" we mean that the second date is the day after the first date then we can do the following:
private bool CheckSequential(DateTime date1, DateTime date2)
{
// strips off time portion
var d1 = date1.Date;
var d2 = date2.Date;
// add 1 to first date
d1 = d1.AddDays(1);
// compare them
if(DateTime.Compare(d1, d2) == 0)
return true;
else
return false;
}

Linq Query with DateTime Compare is not Working as Expected

At approximately 12/1/2014 9:40:12 PM, the following code retrieves a null value.
Campaign camp = repo.Campaigns
.Where(ca => ca.StartTime <= DateTime.Now)
.Where(ca => ca.EndTime >= DateTime.Now)
.FirstOrDefault();
When there is a campaign in the database with the following values:
Start Time:
2014-11-30 00:00:00.000
End Time:
2014-12-02 00:00:00.000
I am at a complete loss why this would occur.
Try this:
Campaign camp = repo.Campaigns
.Where(ca => ca.StartTime.Value.Date <= DateTime.Now.Date && ca.EndTime.Value.Date >=DateTime.Now.Date).FirstOrDefault();
Have you taken timezone information into account? The stored data in the DB might have been created from a computer running in another timezone, your DateTime objects will have another timezone and when they are passed to the database they might exceed EndTime.
Your code works when working with in-memory data so the problem probably has something to do with timezones.
To comment on something else:
1. Don't chain multiple .Where clauses when you can do it with one.
2. Don't use DateTime.Now, store DateTime.Now in a value and then pass it into your LINQ, otherwise you'll compiare StartTime and EndTime against two different values.
var now = DateTime.Now;
Campaign camp = repo.Campaigns
.Where(ca => ca.StartTime <= now && ca.EndTime >= now)
.FirstOrDefault();
You're first opting for a DateTime less than current val. Let's say you got 2 results. Next for these 2 results, you're querying for the DateTime which is more than the current value! The results were less than current Date, so obviously they will never be more than the current Date val. I guess you're trying to do the following:
Campaign camp = repo.Campaigns
.Where(ca => ca.StartTime.Value.Date <= DateTime.Now.Date **||** ca.EndTime.Value.Date >=DateTime.Now.Date).FirstOrDefault();
It is happening because the time you are comparing like StartTime and EndTime are of different date format than the culture your DateTime.Now is picking up
**
DateTime.Now- 12/1/2014 9:40:12 PM
Start Time: 2014-11-30 00:00:00.000
End Time: 2014-12-02 00:00:00.000
**
Change your Datetime.Now date format into the same format as your StartTime and EndTime are
i.e 2014-12-01 9:40:12 PM
And then compare I am sure you will get the result

Linq datetime compare in where clause

I have a table with a couple of columns called Key and Value.
One of the Keys is called RequestedOn and the value is a timestamp saved as a string.
Now in my linq query I would like to compare this timestamp, for example
var startDate = DateTime.Now.AddDays(-7);
var endDate = DateTime.Now;
var query = (from ep in db.ExtendedProperties
where
ep.Key == "RequestedOn" && ep.Value >= startDate && ep.Value <= endDate
select ep).ToList();
Now I know I cannot compare ep.Value (string) against startDate or endDate, and I cannot convert ep.Value to a DateTime as it couldn't make sense. Any ideas on a solution?
Thanks in advance?
if its saved as string you must parse it to DateTime and then compare
You can either:
Convert the DateTime to string
Convert the string to DateTime
Write a method that compares the 2 directly
Something else
Using LINQ for something that does not have a type and contains different data is not a good option. The whole point of LINQ is to have types.
That being said one solution to your problem is to save the date in a format that is comparable as string such as 201405231801 (being 23.05.2014 18:01) and just compare strings.
Of course you care about timezones and daylight saving time you are guaranteed to get it wrong.
If you save your strings right you can actually do a comparison:
For example: '20131201125959': year, month, date, hours, minutes, seconds.

Categories

Resources