In my application I have a datagrid that populates with info from a SQLserver DB. Amongst other things the data which populates the grid includes times. Now I struggled for some time getting the data from the DB to look the way I wanted. In the end my sql comman included the following : -
LEFT(CONVERT(VARCHAR(8), te.StartTime, 8), 5) AS [Start Time],
LEFT(CONVERT(VARCHAR(8), te.FinishTime, 8), 5) AS [Finish Time]
Which nicely shows times in the format of 8:00 & 10:00 etc.
However, this causes a problem later on in my application when I need to use the info in the datagrid to calculate the difference between two times. This is because (I believe) my SQL command (above) has coverted the times to strings. So when I try the following for example:
DateTime startTime = (DateTime)varValue;
DateTime endTime = (DateTime)varFinish;
I get the error message 'invalid cast'. So I'm faced with converting these strings back into DateTime in order to perform any calculations with them. I can't simply add the original time fields to the SQL command, because sometimes the times in the grid will be new times input by the user, so those will be strings anyway.
How should I best convert the user input e.g. "8:00" into a datetime - so that I can perform functions like calucating the difference between two times. Or alternatively, should I be going about the whole timesheet issue a different way.
Any advice will be greatly appreciated. I'm rather new to C# as you may have guessed.
Have you tried this?
DateTime tmp = DateTime.Now;
DateTime startTime = DateTime.Parse(varValue + " " + tmp.ToShortDateString());
DateTime endTime = DateTime.Parse(varFinish + " " + tmp.ToShortDateString());
Think this could solve your Problem?
You got now the current Date with your given times in the two parameters
I advise you to take the date time variables as is without any conversion in SQL, and convert them to the way you want in C#.
you can use the following:
DateTime d = FetchTimeFromDB();
string timeRequired = d.ToString("hh:mm");
It's quite a bad practice to convert your data at the source (database) in a specific format that is dependent on what you need to display in the UI.
In most cases this makes your data virtually not reusable for any other purposes or formats.
You should always try to decouple your application layers and isolate responsibilities.
Your database query should just return the date/time information in the raw format.
Displaying the value in a specific way is a UI-specific requirement that in .NET you can solve using formatting functions (eg ToShortTimeString for a DateTime object).
DateTime t = <date/time form database query>
t.ToShortTimeString(); // or t.ToString("hh:mm");
Related
I am using MS Access as database and using OLEDB. In database I am storing dates as strings. I can't change them in date type (I know it would be easier to work with dates as dates and not strings but I can't change it. I also can't change format of date.).
Date format is dd.mm.yyyy. and DD.MM.YYYY.. What I am trying to do is to compare user typed date with some date from database but I am running into problem.
I don't know what functions to use to convert strings do dates and do comparisons. I tried convert, cast, format, cdate etc. Nothing works. Maybe I am not using it right or I just don't know how to do it. I read some topics here on stackoverflow and solutions doesn't work for me bacause they just directed me to documentations and I obviously can't make it work.
So, let's say I have user typed date 23.07.2021. and column in database named move_date that contains string typed dates and that I want to get all records that have move_date before user typed date.
I guess SQL query should look something like this
SELECT * FROM table WHERE func("23.07.2021.") < func(move_date)
where func should be some function that converts string to date in specific format. I just can't find function that works. I suppose I could frame user typed date with #, so it makes it date literal, but still don't know what to do with column.
Any help is appreciated.
In Access SQL you can nest Replace and DateValue to convert move_date to something that can be parsed. This does two replacements, first it replaces the first two "."'s with "/" and then does a replacement on that to get rid of the last ".". Finally, it parses as a date you can use with a comparison operator.
On the c# side you should convert the user entered value to a date and then make it a parameter:
SELECT *
FROM table
where #searchDate < DateValue(Replace(Replace(move_date, ".", "/", 1, 2), ".", "")) ;
I guess this works for me at the moment. I tested with various examples and can't seem to find example where this doesn't work.
SELECT *
FROM table
WHERE DateValue(Replace(Replace(\"{searchDate}\", \'.\', \'/\', 1, 2), \'.\', \'\')) <
DateValue(Replace(Replace(move_date, \'.\', \'/\', 1, 2), \'.\', \'\'))
searchDate is string (it's not parsed to date)
If someone can find examples where this doesn't work, please share.
In the query, convert those awful text dates to true Date values:
SELECT
*,
DateSerial(Mid(move_date, 7, 4), Mid(move_date, 4, 2), Mid(move_date, 1, 2)) As true_move_date
FROM
table
Now, in your code, call this a query with a parameter for the search date and expand the query with your criteria. This parameter should be passed a normal DateTime value.
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.
I know the question is a bit confusing. Please let me elaborate.
Suppose
I have a table student master which has a column DOB
I have inserted a record and in DOB I have inserted '1991-01-01'
running select statement from sql server is returning date in the same format as it is inserted '1991-01-01' but when I am running the same query from C# using SqlDataAdapter then its returning date as '01-01-1991'
Can anyone explain why it is happening and is there any way to fetch the date in same format as it is inserted.
Query
Is it possible to get the DateTime using SqlDataAdapter as it was inserted?
P.S: column data type is Datetime
let's separate the wheat from the chaff :)
if for your needs meaningful is data type (datetime in this case), then formatting does not matter at all. All layers which will exchange or process the data will use data type information for that.
But
if the meaningful part is formatting, i.e. string representation of the data, then you need to consider the appropriate settings of UI tools you use to display your data. SSMS, for example, uses regional settings for that. If you need to visualize data in the identical manner, so you need the identical strings, you should take care of formatting by your self or in another words, you need to convert your datetime data to string in the same way in all places where you need it.
In T-SQL, for example, you could use CAST and CONVERT functions for formatting your data in a format you need.
If you can't match up the "Cultures" between the SQL Server and the machine you're building the application on (and, in fact, you cannot rely on that really if you're application is going to be deployed to other machines!), then the cheap and quick way round it is to run your date returns through a parse function such as this:
private string FncFormatDate(string date)
{
DateTime formattedDate;
if (DateTime.TryParse(date, out formattedDate))
{
return formattedDate.ToString("yyyy-MM-dd");
}
else
{
return "Invalid date";
}
}
I hope this answers your question.
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