Format DateTime without converting to String in SQL Server? - sql

I have a view in SQL Server 2012 and there is a column of containing dates&times. I have been trying to convert the date column as '20/10/2018 18:00' format (no second) by using this feature and lots of approaches on Stackoverflow and other web sites:
FORMAT(StartDate, 'dd.mm.yyyy hh:mm')
However, as the data type of this column is Varchar (String) rather than DateTime, I encountered some problems in C# side and I want to perform this conversion on the database side without changing the data type of the generated format). Is there any way to achieve this?

SQL Server doesn't have a "date format" per se. The formatting of datetime fields is only performed when presenting the datetime to an output - that is, when converting it to a string.
There is a default format for presentation that is controlled by the server's collation setting. However, internally the date is stored as a numeric value (actual format varies by type, as datetime and datetime2 have different internal formats), and that value has no associated formatting.
You can store your date without seconds by using a smalldatetime field, or by manipulating the input data to trim off the seconds value. But, unless you store your date as a string, which is absolutely not recommended, you will not be able to save an output format different from the default collation-driven format in a datetime field.

I would migrate that column to a datetime (or some variant) if possible. Alternatively if that would affect too many things, you could make a computed column on the table which converts the string date you have to a datetime. That way the database doesn't have to care about the formatting at all; it just works with the proper DateTime data type.
If neither of those is an option, you can just pas the string to C# and use DateTime.TryParse() to convert it to a C# DateTime object.
In either case, it's preferable to work with the date as a DateTime up until the very last minute where you need to format it for display somewhere.

Related

Specify string date format before casting in a function SQL

I have a scenario to cast string date into date format. But the date string is not in a straight format, so the conversion throws error. So what I tried is
set dateformat dmy
before the casting in sql and it worked without any issue.
But the trouble is I need this to implement in a view or function. But the disappointing part, function or view doesn't support set dateformat with which it says as side effecting operator
So how can I specify the date format of the given string before casting in a function or view?
The third parameter of CONVERT() allows to provide a format type.
Assuming your SET DATEFORMAT DMY I take you've to deal with dates like "1/2/2000", meaning the first of February in 2000.
Try this:
DECLARE #d VARCHAR(100)='1/2/2000';
SELECT CONVERT(DATE,#d,104)
The 104 is the German type with a 4-digit year. If this does not fit your needs, you can follow the link to find a better suiting format.
If you need further help, please provide samples of your actual dates.
Hint: You should always store a value in a column with the appropriate type. Storing dates as strings will make things slow and opens a lot of error sources...
As Damien wrote in his comment to the question, ideally you should not mess around with string representations of datetime in the first place - you should be using proper data types - and since you asked about creating a view, it can only mean that somewhere in your database there's a datetime value stored as a string.
The solution to this situation is to change the way you are storing this value - use DateTime2 for datetime values, Date for date-only values, or Time for time-of-day values.
Further reading - Aaron Bertrand's Bad habits to kick : choosing the wrong data type
Assuming you can't change the database design, read the rest of this answer.
You can't use set dateformat on a view or a function, but you can use convert instead of cast to change the string representation of a datetime value into an actual datetime value, assuming the string representation has one of the supported date formats (there are quite a few of them, so usually it shouldn't be a problem).
If your string representation of the datetime is in a format that is not supported by the built in convert function, you might need to do some extra work in the form of string manipulation to either change it into a supported format, or (in the harder case) separate the string representation to parts and then use datetimefromparts.
If you could provide the actual format you are using in your string representation of the datetime format I can probably edit this answer to show you exactly how to do it.
SELECT CONVERT(varchar(10),CAST('07/01/2018' AS DATE),23)
Result
2018-07-01
Not sure what you mean by, "date string is not in a straight format". Examples will help.
Have you tried parsing, instead of casting?
SELECT
TRY_PARSE(thedate AS datetime) as justParse
,TRY_PARSE(thedate AS datetime USING 'en-US') as parseUS
,TRY_PARSE(thedate AS datetime USING 'en-GB') as parseGB
,try_cast(thedate as date) as tryCast
FROM (values
('07/01/2018')
,('01/07/2018')
,('07 jan 2018')
,('jan 07 2018')
,('Monday, 7 January 2019')
)d(thedate)

how to reformat DateTime data type

I know that it is possible to reformat the DateTime data type of the current date and time by using select convert. However, I havent been able to find a method to reformat an existing column (DateTime data type) to: hh:mm:ss yyyy/mm/dd. Or even better, I would like to reformat it to show time only. I dont want to simply convert to time data type because I am working with a chart that accepts either Date or Date time. But what I really want to display on that specific axis of the chart is time. Is there any way to reformat DateTime to my requirements? Thanks.
SQL Server's convert function can take an optional style argument depending upon the datatype. This is how you can get a datetime converted to a string in a variety of formats. For example, try running:
select convert(varchar(30), getdate(), 108) -- returns hh:mi:ss
You can replace getdate() in this example with a column name as well.
There are many styles available, as shown in the documentation.
Note that you will be returning a varchar, so you may want to sort by the original column's datatype.
You can use SET DATEFORMAT but this will change all DateTime's on your SQL Server. You can do some custom formatting, but it will convert the DateTime into a VarChar, so you won't be able to treat it as a DateTime.
SET DATEFORMAT: http://msdn.microsoft.com/en-us/library/ms189491.aspx
I'm not sure if you will be able to use the format you're asking about, though.

Which one is more desired when dealing with dates? sql DateTime or nvarchar string?

Does SQLs built-in DateTime type has any merits over nvarchar type?
If it were you , which one would you use?
I need to store dates in my SQLServer database and I'm curious to know which one is better and why it is better.
I also want to know what happens if I for example store dates as string literals (I mean nvarchar )? Does it take longer to be searched? Or they are the same in terms of performance ?
And for the last question. How can I send a date from my c# application to the sql field of tye DateTime? Is it any different from the c#s DateTime ?
You're given a date datetype for a reason, why would you not use it?
What happens when you store "3/2/2012" in a text field? Is it March 2nd? Is it February 3rd?
Store the date in a date or datetime field, and do any formatting of the date after the fact.
EDIT
If you have to store dates like 1391/7/1, your choices are:
Assuming you're using SQL Server 2008 or greater, use the datetime2 data type; it allows dates earlier than 1753/01/01 (which is what datetime stops at).
Assuming you're using SQL Server 2005 or earlier, store the dates as Roman calendar dates, and then in your application, use date/time functions to convert the date and time to the Farsi calendar.
Use the correct datatype (date/datetime/datetime2 dependant on version and requirement for time component).
Advantages are more compact storage than storing as a string (especially nvarchar as this is double byte). Built in validation against invalid dates such as 30 February. Sorts correctly. Avoids the need to cast it back to the correct datatype anyway when using date functions on it.
If I'm storing a DateTime value, and I expect to perform date-based calculcations based on it, I'll use a DateTime.
Storing Dates as strings (varchars) introduces a variety of logistical issues, not the least of which is rendering the date in a proper format. Again, that bows in favor of DateTime.
I would go with the DateTime since you can use various functions on it directly.
string wouldn't be too much of a hassle but you will have to cast the data each time you want to do something with it.
There is no real performance variance while searching on both type of fields so going with DateTime is better than strings when working with date values.
you must realise the datetime datatype like other datatypes is provided for a reason and you should use the datatype that represents your data clearly.. Besides this you gain all the functionalities/operations that are special to the datetime datatype..
One of the biggest gains is correct sorting of data which will not be possible directly if you use nvarchar as your datatype.. Even if you think you dont need sorting right now there will be a time in the future where this will be useful.
Also date validation is something that you will benefit from. There is no confusion of the dateformat stored i.e dd/mm or mm/dd etc..
There is lot discussed about the subject. There is good post on the SQLCentral forum about this particular subject DateTime or nvarchar.
In short, nvarchar is twice as longer as datetime, so it takes more space and on the long range, any action affecting it will be slower. You will have some validation issues and many more.

Access SQL Date Format

How can I retrieve a record based on a Date property? I'm trying:
WHERE Meetings.[MDate] = '16/12/2011'
which is the format I use but I get :
"Data type mismatch in criteria expression"
Problem solved: It should have been:
WHERE Meetings.[MDate] = 16/12/2011
No quotation marks.
For where clauses use
columnName = #mm/dd/yyyy#
You'll want to use the SQL date format: '#2011-12-16#'
Use the cast to DATETIME function, CDATE(), which will honour the machine's regional settings. That said, it still a good idea to use an unambiguous date format and the ISO 8601 format is a good one.
Also note that Access doesn't have a date data type: its sole temporal data type is DATETIME and, as its name suggests, always has a time element accurate to one second time granule, even if that time happens to be midnight. Therefore, it is a good idea to always include a time value to one second time granule in all DATETIME literals e.g.
WHERE Meetings.MDate = CDATE('2011-12-16 00:00:00');
Another advantage to the above is that the Access UI will not attempt to reformat the DATETIME literal because it is held as a string.

Sorting a time value in a dataset

In my current solution, I am converting a DateTime value, "Time" in my database using CONVERT so it displays in a ##:##AM/PM format, and I realize that CONVERT just takes whatever datatype and turns it into a VarChar, or a String once its in C#. This is making my sort work incorrectly in my Gridview. I am sorting the columns in my DataSet returned from my stored procedure. However it isnt sorting by AM/PM since its a string literal, and not a DateTime.
What is the best way to sort Time values? Should I use a different datatype, like TIME in my database? Different CONVERT command? I'm stumped! I can't use a 24 hour format, that's the only restriction. Thanks!
A couple of thoughts:
Could you use AM 01:23 / PM 01:23 format - this would sort well.
If you can return the times from the database in DATETIME format, but with the date set to some 'constant date' (e.g. 2000-01-01 hh:mm), you could almost certainly put a format string on the GridView column to display just the time, whilst still enabling sorting by the underlying value.
I use ticks: http://www.codeproject.com/KB/database/DateTimeToTicks.aspx
Or (if possible) DateTime - and handle it in my grid.
You can add an additional column with the date/converted date which is hidden in you gui but used to sort.