UTC in DB confusion when querying in linq from Web API server - c#

I can really use some help wrapping my head around a problem I'm having querying data according to a SQL Date field.
I am storing the Date in UTC format using the following code:
objFitCalendarDto.Day = objFitCalendarDto.Day.ToUniversalTime();
That line assigns the date to the model that is inserted into the db through Entity Framework.
Now, my query is supposed to retrieve a row based on a date. So, I should be able to get the row for today, tomorrow, yesterday, and so on.
To do this, I'm using the method to search between two dates, a start date and an end date as follows:
DateTime dayBegin = DateTime.Today.Date.AddDays(dayOffset);
DateTime dayEnd = DateTime.Today.Date.AddDays(dayOffset + 1);
The purpose of dayOffset is to specify which day. If Offset is 0, then I am searching for Today. If dayOffset is 1, then I am searching for rows with tomorrow's date.
Now, since I stored the data originally in UTC, I am assuming that I must search for it in UTC as well. So before executing my query, I convert the dates to UTC like so:
dayBegin = TimeZoneInfo.ConvertTimeToUtc(dayBegin);
dayEnd = TimeZoneInfo.ConvertTimeToUtc(dayEnd);
Then I execute my query like so:
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
f.DayAsDate >= dayBegin && f.DayAsDate < dayEnd
select f);
problem is, it doesn't work. I have a row with the date, "2016-01-26" when I look at it in SQL Manager. However, it only returns from a query on yesterday's date. Today is 2016-01-26, by the way. Clearly I'm not getting this UTC concept. Can anyone see what I'm doing wrong here? I was assuming that if I stored everything as UTC and then before querying I converted my dates for the query to UTC, that everything should work.

UPDATE
Let's try like this:
As soon as you are storing only date part (SQL 'date' type), you
need to compare also only dates.
Instead of
DateTime dayBegin = DateTime.Today.Date.AddDays(dayOffset);
dayBegin = TimeZoneInfo.ConvertTimeToUtc(dayBegin);
let's just do
DateTime dayBegin = DateTime.UtcNow.Date.AddDays(dayOffset);
dayBegin in that case will be date with time anyway (time is 12:00:00 AM). It means, we need to truncate it with DbFunctions. We need equality check here.
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
f.DayAsDate == DbFunctions.TruncateTime(dayBegin)
select f);
END OF UPDATE
I believe that problem is that you comparing dates with times. In your case you need to compare only dates, as far as I understand. As a solution - use DbFunctions TruncateTime function. It can be used within linq queries - like in your code.
https://msdn.microsoft.com/en-us/library/system.data.entity.dbfunctions.truncatetime(v=vs.113).aspx
So, complete solution would be
var query = (from f in Db.FitCalendars
where f.FitProgramId == programId &&
DbFunctions.TruncateTime(f.DayAsDate) >= DbFunctions.TruncateTime(dayBegin) && DbFunctions.TruncateTime(f.DayAsDate) < DbFunctions.TruncateTime(dayEnd)
select f);

Related

how to find date range between two dates in days format using linq c#

I have a requirement for generating report in form of 15 days,30 days,45 days.
I have to compare the list data which is coming from db with current date.example if difference is 5days. It is less than 15,so i should send to 15 days ,if >15 i should send to greater than 15etc.How to write linq query for this.can any one help on this please
I'm not sure that can be possible to make this in only one query.
But, I can propose you another solution.
Instead of one query, you can use one query for every case.
In order to compare date difference, you can use SqlFunctions Class.
For this, you should use :
using System.Data.Objects.SqlClient;
Here is the query for 5 days with an imaginary table and fields :
var lstDiff5 = (from ro in dc.Commandes where
SqlFunctions.DateDiff("DD", ro.Cmd_PromisDate, DateTime.Now) <= 5
select ro).ToList();
The DateDiff Function takes the date part (DD for days), the start date and the end date. In my case the start date is the current date.
And for 15 days :
var lstDiff15 = (from ro in dc.Commandes where
SqlFunctions.DateDiff("DD", ro.Cmd_PromisDate, DateTime.Now) > 5 &&
SqlFunctions.DateDiff("DD", ro.Cmd_PromisDate, DateTime.Now) >= 15
select ro).ToList();
You can change the operators > et >= depending your need.
At the end, you can fill your report using all of your lists or you can merge your lists into a new list in order to bind your report to your final list.
You can use DaysBetween function in linq.It will return all dates betwee the given dates.
Example:
DateTime dt = DateTime.Today.Date.AddMonths(1);
int d = dt.DaysBetween(DateTime.Today).ToList().Count;

Using an if statement to check if a date is more than a year c#

var carID = taxBDO.Customer_Id;
Customer customerInDb = (from p in TaxEnitites.Customers
where p.Customer_Id == carID
select p).FirstOrDefault();
if (customerInDb.Date_Taxed < 365)
{
}
I have retrieve a date from my db that I have set up, however I can not figure out to use an if statement t use this date from my database to check if this date is more that a year ago,
any help would be appreciated
Thanks
You can add negative one years to today and compare:
customerInDb.Date_Taxed < DateTime.Now.AddYears(-1)
Yes. You can compute a timespan between now and then and fetch the total number of days.
DateTime.Now.Subtract(customerInDb.Date_Taxed).TotalDays > 365
Crowcoder has already given a solution which will work in most cases.
But, dateTime.Now has the Time component as well! So, if
customerInDb.Date_Taxed = {15/11/2014 00:05:30}
DateTime.Now = {15/11/2015 00:22:30}
Then
Date_Taxed < DateTime.Now.AddYears(-1) => true
Though it's on the same date last year. And this calculation will depend on the current time, so you'll get different results at different time of the day.
If you want this, then fine. Else, you can compare just the Date part as
var isMoreThanYearAgo = customerInDb.Date_Taxed.Date < DateTime.Now.AddYears(-1).Date;
Also, check customerInDb for null before you call this, as you are getting this as a result of FirstOrDefault().

Simple.Data subtract days from date time in where clause

I am using Simple.Data (version 0.19.0.0) against a SQL Server back end database and would like a query such as the one below to take 25 days from a date to compare against the date now;
DateTime dtNow = DateTime.Now.Date;
var pool = db.Pools.FindAll(db.Pools.Status == 1
&& db.Pools.EndDate - 25 > dtNow)
.Select(db.Pools.AllColumns());
I have tried using DATEADD but get an error that the function is not recognised, I guess because the column name is not the first parameter of the method.
Is this kind of thing possible in Simple.Data, or should I ignore the date in the query and perform the check in a foreach loop following?
Thanks in advance.
Try like that;
DateTime dtNow = DateTime.Now.AddDays(-25).Date;
var pool = db.Pools.FindAll(db.Pools.Status == 1
&& db.Pools.EndDate > dtNow)
.Select(db.Pools.AllColumns());
I overcame the problem by using a where clause on my query with a >= and < date range as suggested in how to search by date question.

Get records of last week adding by datetime in database

I'm using asp.net MVC in my project. My database table includes some records. The table has datetime column for records. I want to get records of last week adding. So the LastlyRecords is:
DateTime.Now = 04.04.2015
LastWeekDateTime = 28.04.2015
LastWeekDateTime < LastlyRecords < DateTime.Now
Have a method that accepts a "Start Date" and "End Date" as parameters.
Call it with a start/end date like:
GetRecords(DateTime.Now.AddWeeks(-1), DateTime.Now);
For there, you can have a stored procedure fetch records between that date range (or do something similar for Entity Framework or whatever you're using).
You can do something similar in T-SQL via GETDATE() and DATEADD(), but it's arguably better to do the range calculation in the calling code (because it's more a business logic thing than a data access thing).
you have to write logic on your query or you can modify below as per your datetime range.
var lastweek = DateTime.Now.AddDays(7);
var records = d in db.Persons
where DateTime.Compare(lastweek, d.DateRecordColumn)
and DateTime.Compare(d.DateRecordColumn, DateTime.Now)
select d;
hope this help to resolve your query!!!
string dateTime = "01 April 2015 Wednesday 16:23";
DateTime time1 = Convert.ToDateTime(dateTime);
if (DateTime.Compare(DateTime.Now, time1) == 1 && // DateTime.Now > time1
DateTime.Compare(time1, DateTime.Today.AddDays((int)-7)) == 1 // time1 >= DateTime.Now-7days
)
{
#("True.")
}
else
{
#("False.")
}
The result is true, so it is in last week.

C# MySQL LINQ DateTime conversion

I'm trying to retrieve records from a mySQL DB using LINQ and C#.
The date in c# code is a string: 23-01-2010
I need to convert this to DateTime format as 2010-01-23 (mySQL default DateTime format), otherwise the query does not return any records, at present it errors saying a string cannot be matched against a DateTime (row.DateOfIssue)
If I convert the string to DateTime (C#), then it is not in the mySQL DateTime format of yyyy-MM-dd
String endDate = "23-01-2010";
var query = (from row in uow.UserPersonalLicenseDetails
where (endDate >= row.DateOfIssue && endDate <= row.DateOfExpiry)
select row)
This is such a standard query it seems mad that it is so hard to do in LINQ.
It seems putting any method like CompareTo etc in the where clause causes an error of "Search for a class that works in this scenario"
I'm now wondering if the best line of attack might be to write a stored procedure in the database. This could then take the C# datetime as a parameter, convert it to mySQL format and then run the required query.....
Any thoughts?
Make it a DateTime - so
var myDate = DateTime.Parse(endDate);
Then
myDate.ToString("yyyy-MM-dd");
---------- or this:
var myDate = DateTime.Parse(endDate);
var query = (from row in uow.UserPersonalLicenseDetails
where ((myDate.CompareTo(row.DateOfIssue)>=0 && (myDate.CompareTo(row.DateOfExpiry)<=0)
select row
Just convert your date string to DateTime and then in the LINQ convert the string to DateTime that's coming back in order to do the comparison. I've used ParseExact because we need to make sure that we are parsing to the exact format that MySQL stores the date in, which is yyyy-MM-dd hh:mm.
Something like:
var endDate = DateTime.Parse("23-10-2010").ToString("yyyy-MM-dd hh:mm");
var formattedEndDate = DateTime.Parse(endDate);
//you could cut that to one line by putting the date in said format in the first place
var query = (from row in uow.UserPersonalLicenseDetails
where formattedEndDate >= row.DateOfIssue
&& formattedEndDate <= row.DateOfExpiry
select row)
Ok, problem was that the Table had the field defined as DATE rather than DATETIME so no match was being made.
Used DateTime.Date and the match was made.

Categories