In UI I have two date picker fields that user can select start and end date of his search. ( No time value entry, just date part) So for example he can enter the same date for both start and end of his criteria if he wants to only see the records for that one specific date.
Now in SQL Server those columns are stored as DateTime fileds with values like
'2013-04-04 10:48:02.830'
So because it keeps the time part in SQL Server too, then my searches return no result when the start and end date is the same in C# part.
How can I fix this on C# side? ( I am assuming there is a use case for the time part that we keep in SQL Server in some other part of the application so don't want to mess with back-end section).
So: SQL Server has values like '2013-04-04 10:48:02.830'
C# is passing values like {11/26/2011 12:00:00 AM}
And when the start and end date are the same, we get no results.
Assuming you have code on the back end that go to SQL Server for you, instead of having a UI that is data bound:
You simply take the two values you get from the UI and modify them as needed:
DateTime from = originalFromDate.Date;
DateTime to = originalToDate.Date.AddDays(1).AddSeconds(-1);
and now if you search for anything that is between from and to, you'll find your records:
(in case of LINQ:)
var query = queryUntilNow.Where(x => x.Date >= from && x.Date <= to);
Related
I have the following datetime range:
22/07/2021 07:00:52 (start date)
22/07/2021 07:01:00 (end date)
I want all the data between this range including the right hand boundary.
My linq to SQL query:
Select * from tableName where CreatedAt >= startDate and CreateAt <= endDate
The issue here with the query is I am unable to get the record whose CreatedAt= 22/07/2021 07:01:00 (end date). If I do AddMinutes(1) to the endDate, I get the required datas but I also get the data greater than endDate.
For example data having following Created At dates
22/07/2021 07:01:15
22/07/2021 07:01:20
which is faulty.
How do I include the right boundary in the range comparison for datetime?
I have tried removing the miliseconds from the database record as:
select * from Custom_Devices
where
DATEADD(ms, -DATEPART(ms, CreatedAt), CreatedAt) >= '2019-07-29
19:00:00'
and
DATEADD(ms, -DATEPART(ms, CreatedAt), CreatedAt) <=
'2019-07-29 19:01:00'
Attaching a screenshot of the output:
Expected output:
Update: CreatedAt column is a datetime2 column in database.
f I do AddMinutes(1) to the endDate
Not sure why you'd add a whole minute when the problem is caused by additional milliseconds and can be solved by going up a second..
Do you actually want to keep the milliseconds on the dates? Is it any use to you to know that the event occurred at 12:34.56.789 rather than 12:34:56? If not, make the column a datetime2(0) to discard the milliseconds permanently
Otherwise I recommend the route several other people are also advocating and do your LINQ like
context.Whatever.Where(x => x.CreatedAt >= startDate && x.CreatedAt < endDate.AddSeconds(1))
The "less than" is vital. A "less than 12:34:57" will get 12:34:56.999999... which appears to be what you want with your "less than or equal to 12:34:56"
If you're struggling to understand why milliseconds cause a problem, think of dates like numbers - if you have a number 1.222222 and you ask the db for "less than or equal to 1.2" the DB doesn't auto-round the 1.222222 down to 1 decimal place and then go "oh it's equal to 1.2" and return it. It just goes "1.222222 is not less than or equal to 1.2, don't return it"
Over time for question like this you'll always get someone who says "just cast it to.." or "run this to calculate a new date to remove the milliseconds..." - don't; if you write a query that manipulates the table data, that manipulation has to be performed every time the data is queried. It typically kills the ability for the db to use an index on the column too (the db will probably switch to running the manipulation on every value in the index, every time) which means the query is massively more resource intensive.
Always consider manipulating table data in a where clause as an absolute last resort. If there is no other way and the query will be heavily used, look at adding some kind of calculated column to the table and index it so that, conceptually, the result of the manipulation you're carrying out is done once and an index on it can be used
In my Windows Form C# Application, I am inserting the record into the SQL server database. Along with other fields, I am also inserting both the current date and current time using the following format:
DateTime currentDate = DateTime.Now;
string SaleDate = currentDate.ToString("dd-MM-yyyy");
DateTime currentTime = DateTime.Now;
string SaleTime = currentTime.ToString("hh:mm:ss tt");
Which works fine and the records are inserted successfully with Date and Time format like .
However, when I select records between two dates, I am unable to perform this operation. I am sure that there is no problem in this custom format of my date because I have edited the same format several times and even I have saved the date in its default format but still I am unable to select the target records (between two dates)
I am using the following select query in my application to select records from the view vAllSales which results in selecting either all the records or records whose SaleDate does not meet the specified filter criteria:
select * from vAllSales where SaleDate >= '20-04-2019' and SaleDate <= '30-04-2019'"
I have tried the following queries in my SQL server as well to inspect the cause:
1.
select * from vAllSales where SaleDate between '21-04-2019' and '09-05-2019'
The above query does not return any value. Like
2.
select * from vAllSales where SaleDate >= '21-04-2019'
The above query select only a few records. Because 21-04-2019 is the initial SaleDate and the query should return all of the Sales but it only returns a few records, like .
Is there any issue with the specified date format within my code? Or do I have to work on improving my queries? I need a more professional and reliable approach for this case.
You should store your date and time as datetime2 objects in your database.
It will give you the benefits of:
better sorting: (your current string format does not allow a natural sort)
better performance; since your date and times are represented as numbers in stead of strings
easier to handle in code and queries: since it maps directly to a C# DateTime object.
For more info on database types see:
https://learn.microsoft.com/en-us/sql/t-sql/data-types/datetime2-transact-sql?view=sql-server-2017
And perhaps:
https://learn.microsoft.com/en-us/sql/t-sql/data-types/time-transact-sql?view=sql-server-2017
If you absolutely must use a string to represent your date, make sure it's in the sort-able ISO format.
YYYY-MM-DD
due to the nature of this format it's lexicographical sort-able as a string type.
You are trying to apply logical operations to string values. What will here happen is lexicographical comparing. (left to right).
So you better use correct data types to store data in table.
But If you really want to store date as a string, you have to cast them to proper data types before comparison.
select * from vAllSales where CAST(SaleDate AS DATE) >= '21-04-2019'
Keep note that ms sql server uses single quotes for pass datetimes. That doesn't mean those are strings or varchar
I am having hard time to store date information into the datetime column of SQL Server.
I get the input from the user for three columns:
Creation Date
Preparation Date
Next Preparation Date
I use calendarextender and format the date as "yyyy/MM/dd". When all the fields have date, they are stored in the DB as for instance, 16-10-2016 (dd-MM-yyyy).
At this point I have two issues:
These columns are optional, when some of them are empty my code does not work (I assume because datetime cannot be null). To overcome this, I am using the following code snippet but still does not work.
DateTime? creationDate= null;
if (creationDateTextbox.Text != null && creationDateTextbox.Text != "")
{
creationDate= Convert.ToDateTime(creationDateTextbox.Text);
}
When I fetch the dates from DB, they are shown as 10/16/2016 (MM-dd-yyyy) which is different how I formatted it. I would like to show it in the format user enters them.
Dates do not have a format while stored in a database. It is actually usually just a very large long that counts the number of milliseconds from a set starting date.
If you want to store the format you need to stop storing it as dates and instead just treat the text as text in the database, however if you do this you won't get the advantage of sorting or filtering by a date range because it will just be seen as text.
Date time doesn't have any format You can format is as a string, suppose your DateTime type database field dt which contain date as 10/16/2016 (MM-dd-yyyy) then you can convert it
string s = dt.ToString("yyyy/MM/dd");
The answer to one of your questions is here: MSDN
You can use data annotations to format the dates that you get from your SQL DB. I'm assuming that you're using EF6; if not, you can change the field to a varchar in SSMS, and store the date as a String.
And the second, I'm unclear about, but if what you want is for your SQL DB column to be optional, you can use the Optional data annotation for that.
this is my first question so pardon any mistakes that might occurs :)
I made a C# program that collects data from SQL Server Database using Datatables, and then export the results to Excel spreadsheets using Interop.
The program itself runs well and doing as it should; however, I found some bugs when it tries to select data with Date columns less than or equal to i.e. 2014-05-31 23:59:59.
Supposed I tried to get all data up to May 1st 2014.
My code first initiates the "Start Date" parameter for the SQL Command later used like this:
var firstDay = new DateTime(today.Year, today.Month, 1); //2014-05-01 00:00:00`
based on firstDay, it initiates the date for the parameter
var periodTo = firstDay.AddSeconds(-1);`
I debugged and got the time I wanted: 2014-04-30 23:59:59
After adding some more parameters for the data criteria, it executes the method to run the query using the parameters supplied.
queryResult = medicore.GenerateRegister(ConfigurationManager.AppSettings["queryDir"], ConfigurationManager.AppSettings["queryName"]);`
The periodTo parameter will be mapped to #EDate variable in the SQL Script. #EDate is declared as Datetime. The #Edate comes into play here:
Select columns
From tables
Where Voucher.Date <= #EDate
which I suppose, the script will be looks like Where Voucher.Date <= '2014-04-30 23:59:59'
The problem is, the result in the Excel file generated also consists of data from '2014-05-01', which is not supposed to be there...at least based on the criteria I set.
Is there some kind of rounding happened between C# and SQL Server?
Thanks!
The reason for this is probably that Voucher.Date is a SMALLDATETIME, therefore you are implicitly converting '2014-04-30 23:59:59' to a SMALLDATETIME:
SET DATEFORMAT MDY;
SELECT CONVERT(SMALLDATETIME, '2014-04-30 23:59:59')
Which gives '2014-05-01'.
Why not just use the Less than operator, instead of less than or equal to?
SET DATEFORMAT MDY;
SELECT ...
WHERE Voucher.Date < '2014-05-01';
N.B I have explcilty stated the DATEFORMAT because yyyy-MM-dd (despite being an ISO standard) is not culture invariant for the DATETIME and SMALLDATETIME data types in SQL Server, and if (like me) you are in a country where the default date format is DMY then SELECT CONVERT(SMALLDATETIME, '2014-04-30') will give you a conversion error. yyyyMMdd is the only culture invariant date format for these two types.
An excellent, and very relevant article to read is Aaron Bertrand's Bad habits to kick : mis-handling date / range queries
I have a table with two separate columns for date and time (SQL Server 2008).
I am trying to get the data between 1 minute before current time and 1 minute after current current time in my asp.net MVC (C#) application.
I have tried to use the where condition as:
ce.Start_Date.Add(ce.Start_Time) >= _currDateTime.AddMinutes(-1) &&
ce.Start_Date.Add(ce.Start_Time) <= _currDateTime.AddMinutes(1)
But from the above where condition, it throws an error:
The datepart millisecond is not supported by
date function dateadd for data type date.
How can I correct/rectify this error?
Don't add the minutes in the where clause, try something like this instead:
for ce in data
let start = _currDateTime.AddMinutes(-1)
let end = _currDateTime.AddMinutes(1)
where ce.Start_Date.Add(ce.Start_Time) >= start &&
ce.Start_Date.Add(ce.Start_Time) <= end
select ce
LINQ to SQL is attempting to translate your where clause into valid T-SQL (using T-SQL's dateadd function) and it is having trouble doing so.
The problem seems to be with server DATE type which does not have proper SQL translation.
Try to make LINQ convert Date to DateTime, something like this:
Convert.ToDateTime(ce.Start_Date).Add(ce.Start_Time)
Converted to .AsEnumerable() and manipulate the date and time and return as .AsQueryable();
Simplest way to add "update time" field in table and compare current time with this field.