Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Date and time between a date range in dotnet

I am facing the problem to know if DateTime is between a date range in the dotnet.

For example if the x.SchedulerStart value is 2022-11-02 06:46:30 and x.SchedulerEnd value is 2022-11-02 23:26:30. I want check this DateTime.Today value is inside the date range, but below coding is doesn’t work. I have look at this StackOverflow question still cannot work How to know if a DateTime is between a DateRange in C#

Below is my coding:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

x.SchedulerStart.Date >= DateTime.Today && x.SchedulerEnd.Date <= DateTime.Today

Whole code:

List<SAASMsgSchedulerForQueueList> msgSchedulerList = await _saasdbContext.SaMsgScheduler.AsNoTracking().Where(x => (x.Enabled == true && x.SchedulerStart.Date >= DateTime.Today && x.SchedulerEnd.Date <= DateTime.Today) &&
    ((x.SchedulerRecurring == "Daily" && x.RecurringTime == currentTime) || (x.SchedulerRecurring == "Weekly" && x.RecurringWeekday == weekDayNumber && x.RecurringTime == currentTime) ||
    (x.SchedulerRecurring == "Monthly" && x.RecurringDay == currentDay && x.RecurringTime == currentTime) || (x.SchedulerRecurring == "Yearly" && x.RecurringMonth == currentMonth && x.RecurringTime == currentTime)))
    .Join(_saasdbContext.TnMsgTemplate.AsNoTracking(),
    schedule => schedule.TemplateId,
    template => template.Id,
    (schedule, template) => new { schedule, template })
    .Join(_saasdbContext.SaMsgQuery.AsNoTracking(),
    schedule => schedule.template.QueryId,
    query => query.Id,
    (schedule, query) => new SAASMsgSchedulerForQueueList()
    {
        ID = schedule.schedule.Id,
        BranchID = schedule.schedule.BranchId,
        TemplateID = schedule.schedule.TemplateId,
        TemplateContent = schedule.template.TemplateContent,
        Query = query.QuerySql,
        MessageType = schedule.schedule.MessageType,
        RecurringDatetime = schedule.schedule.RecurringDatetime,
    }).ToListAsync();

Hope some one can guide me on how to solve this problems. Thanks.

>Solution :

You need to reverse the condition. Right now you’re looking for something that started after today and ended before today.

It’s better to write the query in a form that reflects what you want, ie Today is between the start and end dates :

x.SchedulerStart.Date <= DateTime.Today && DateTime.Today <= x.SchedulerEnd.Date 

Better, as in after 20 years I still mix things up if I put the field on the left side of such a query. One shouldn’t have to translate an expression to understand what it does

Another improvement is to avoid .Date. This results in a cast(ScheduleStart as date) in SQL Server. Normally such a cast would prevent the use of indexes. SQL Server is smart enough to convert this into a range query but can’t use any indexes gathered for the ScheduleStart column and can still end up with an inefficient execution plan.

.Date can simply be removed from DateTime.Today <= x.SchedulerEnd.Date. If the end date is today, DateTime.Today <= x.SchedulerEnd holds no matter the time.

To eliminate .Date from the opening date, compare it to the next day, ie x.SchedulerStart < DateTime.Today.AddDays(1). If the start day is today, that will hold for every time. If SchedulerStart is on the next day, the condition will still be false.

A correct and efficient condition will be :

x.SchedulerStart < DateTime.Today.AddDays(1) 
&& DateTime.Today <= x.SchedulerEnd

The query is targeting MySQL using Oracle’s official EF Core provider, MySQL.EntityFrameworkCore, which has several known problems, which are fixed on Oracle’s own schedule. That’s why almost everyone uses the truly open source Pomelo.EntityFrameworkCore.MySql. Everyone as in 29.3M downloads for Pomelo vs 1.7M downloads for Oracle’s provider.

In this case, Oracle’s provider fails to treat DateTime.Today.AddDays(1) as a constant and tries to convert it to a SQL expression.

To avoid this problem, calculate the dates before the query, eg:

var today    = DateTime.Today;
var tomorrow = today.AddDays(1);

...
x.SchedulerStart < tomorrow && today <= x.SchedulerEnd
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading