Convert VARCHAR in French/France Date format to Date - sql

I'm having some issues with date conversions and have tried a lot of the previous posts. However, most of the previous posts seem to tackle converting English Dates to other Cultures and vice versa.
Here's the problem:
I have a date in 'String' format that get's passed into a variable. I want to cast that into a date WITHOUT changing the language. I want to do this so that I can look through records between dates.
DECLARE #style INT
DECLARE #recordDate DATE
DECLARE #srchDateBegin NVARCHAR(30)
DECLARE #localeID NVARCHAR(10)
SET #localeID = '1036'
SET #srchDateBegin = '13/04/2022'
SELECT #style = CASE WHEN #localeID = '1036' THEN 103 ELSE 101 END
This is all the declaration stuff (the structure is a bit different but I've written it out this way to make it a bit simpler. Below is one way I've tried converting everything but that didn't work:
-SQL SELECT STUFF-
AND (#srchDateBegin = ''
OR #recordDate BETWEEN CONVERT(NVARCHAR(30), CAST(#srchDateBegin AS DATE), #style) AND ...
I then tried to use the FORMAT function in SQL but it doesn't want NVARCHARs but because I can not cast an NVARCHAR format of '16/02/1996' into a DATE, I'm stuck
AND (#srchDateBegin = ''
OR #recordDate BETWEEN
CASE WHEN #style = '103' AND '#srchDateBegin' <> '' THEN FORMAT(#srchDateBegin, 'dd/MM/yyyy') ELSE '#srchDateBegin' END AND ...

Try this:
DECLARE #srchDateBegin NVARCHAR(30)
SET #srchDateBegin = '13/04/2022'
SELECT CONVERT(DATE, #srchDateBegin, 105)

Based on what you've written, you're actually converting something into NVARCHAR and not the other way around.
Syntax for CONVERT and CAST:
-- CONVERT syntax:
CONVERT(data_type(length), expression, style)
-- CAST syntax:
CAST(expression AS data_type(length))
Note: Only data_type and expression are required; length and style are optional.
Suggestion:
-- your code:
CONVERT(NVARCHAR(30), CAST(#srchDateBegin AS DATE), #style)
-- suggestion:
CONVERT(date, #srchDateBegin, #style)
Sources:
Quick info from W3Schools.
Comparing CAST and CONVERT from Microsoft's documentation.

Related

SQL datetime incorrect format when declaring variable

I am trying to figure out why this example does not work as expected. I am using SQL Server 2017.
DECLARE #testDate DATETIME = CONVERT(VARCHAR(10), GETDATE(), 110)
SELECT CONVERT(VARCHAR(10), GETDATE(), 110)
SELECT #testDate
The first select gives the correct format but instead the second select gives incorrect format. The same happens when i try to cast it from NVARCHAR. Can someone explain to me why this is happening? It's like the variable is not properly storing the result of convert.
EDIT: You can see the results below the first select returns a different format than the second one.
EDIT2: Thank you for your answer but my question was quite specific on why those 2 selects return different results and it was mainly educational. Not to analyze all the business requirements, I gave 3 lines and i asked why I am getting those results. Simple as that. What i did not understood/notice was that the datetime object was casting the result of the CONVERT to a different format by itself.
You are converting Varchar to DateTime
See these examples:
DECLARE #testDate2 DATETIME = '08-27-2019'
SELECT #testDate2
DECLARE #testDate3 DATETIME = '2019-08-27'
SELECT #testDate3
SQL always convert values to default DateTime format.
Both of them converted to 2019-08-27 00:00:00.000
In this case SELECT CONVERT(VARCHAR(10), GETDATE(), 110), your selecting formated Nvarchar. style 110 => mm-dd-yyyy
If you want to store converted DateTime you can use like this:
DECLARE #testDate4 VARCHAR(10) = CONVERT(VARCHAR(10), GETDATE(), 110)

Converting Nvarchar(MAX) to DATETIME Datatype SQL Server query

I'm having issues converting a NVARCHAR(MAX) to a DateTime datatype. I have checked for nulls and empty spaces. I'm not really sure why it isn't converting. Is it maybe because of they way it has the data in there now. If anyone could tell me what I have to change for it to work.
DateStamp
------------------
2015-10-1413:09:17
2015-10-1413:09:17
2015-10-1413:09:19
2015-10-1413:09:22
2015-10-1413:09:23
2015-10-1413:09:27
2015-10-1413:09:27
DateStamp is the column as you can see. Is there spaces that have to be put in or is there something else I have to change?
Your NVARCHAR(MAX) strings have a missing space. For example '2015-10-1413:09:17' should be '2015-10-14 13:09:17'
As you state, this will not work when converting to DATETIME:
DECLARE #date NVARCHAR(MAX) = '2015-10-1413:09:17'
BEGIN
SELECT CAST(#date as datetime)
SELECT CONVERT(datetime,#date)
END
Conversion failed when converting date and/or time from character
string.
Assuming you're always going to get this datestamp string in the same format, you could use SUBSTRING to add the required space to the string, then convert it to a DATETIME:
DECLARE #date NVARCHAR(MAX) = '2015-10-1413:09:17'
BEGIN
SELECT (SUBSTRING(#date,1,10)+' '+SUBSTRING(#date,11,15)) as FormattedDate -- 2015-10-14 13:09:17
SELECT CONVERT(datetime,(SUBSTRING(#date,1,10)+' '+SUBSTRING(#date,11,15)))
END -- Returns : 2015-10-14 13:09:17.000

Convert varchar data to datetime in SQL server when source data is w/o format

How can I convert VARCHAR data like '20130120161643730' to DATETIME ?
CONVERT(DATETIME, '20130120161643730') does not work.
However, CONVERT (DATETIME, '20130120 16:16:43:730') works. I guess it needs data in correct format.
Is there a valid way that can be used to convert to DATETIME directly from unformatted data ?
My solution is :
DECLARE #Var VARCHAR(100) = '20130120161643730'
SELECT CONCAT(LEFT(#Var,8),' ',SUBSTRING(#var,9,2),':',SUBSTRING(#var,11,2),':',SUBSTRING(#var,13,2),':',RIGHT(#Var,3))
It works fine. However, I'm looking for a compact solution.
You can make it a little more compact by not forcing the dashes, and using STUFF instead of SUBSTRING:
DECLARE #Var VARCHAR(100) = '20130120161643730';
SET #Var = LEFT(#Var, 8) + ' '
+ STUFF(STUFF(STUFF(RIGHT(#Var, 9),3,0,':'),6,0,':'),9,0,'.');
SELECT [string] = #Var, [datetime] = CONVERT(DATETIME, #Var);
Results:
string datetime
--------------------- -----------------------
20130120 16:16:43.730 2013-01-20 16:16:43.730
DECLARE #var VARCHAR(100) = '20130120161643730'
SELECT convert(datetime,(LEFT(#var,8)+' '+SUBSTRING(#var,9,2)+':'+SUBSTRING(#var,11,2)+':'+SUBSTRING(#var,13,2)+':'+RIGHT(#var,3)))
The only possible way to convert this type of string to date time is to break it and then convert it to DateTime. Also, Concat doesnt work in MS SQL but "+".
Assuming this format is something you work with regularly, something more compact would be to create a UDF (user defined function) that parses the string into a valid datetime.
So something along the lines of:
create function dbo.ParseDate (#var varchar(max)) returns datetime as
begin
return (convert(datetime,(LEFT(#var,8)+' '+SUBSTRING(#var,9,2)+':'+SUBSTRING(#var,11,2)+':'+SUBSTRING(#var,13,2)+':'+RIGHT(#var,3))))
end
You could then select from that function like this:
select dbo.ParseDate('20130120161643730')
So any code that needed to reference the date would be more compact.

Char to DateTime Conversion

I have one column capturedatetime(Char(30)):
2006-04-25T15:50:59.997000 PM
And I want to convert it and load it at other table column which have is in DateTime. either by T-sql or SSIS which ever way.
I have tried with:
select CONVERT(datetime, '2006-04-25T15:50:59.997000 PM', 126)
But it creates an error:
Conversion failed when converting date and/or time from character string
Late update:
In this column I also have other data that is in a completely different format:
29-JAN-10 08.57.41.000000 PM
(1) STOP storing datetime data in string columns! This is nothing, nothing, nothing but trouble.
(2) Why on earth does your column get data in two different string formats that aren't even valid? Why does the string use 24 hour time and have AM/PM suffix? Why use a regional string format and Y2K disaster like 29-JAN-10?
Here is one way, but it's awfully ugly. I highly recommend you fix the SSIS process to give you valid datetime values in the first place, if not as datetimes, at least as valid ISO strings (yyyy-mm-ddThh:mm:ss.nnn):
DECLARE #x TABLE (d CHAR(30));
INSERT #x SELECT '2006-04-25T15:50:59.997000 PM'
UNION ALL SELECT '29-JAN-10 08.57.41.000000 PM';
SET LANGUAGE ENGLISH; -- this is important, else style 6 may not work
SELECT
CASE WHEN d LIKE '__[0-9]%' THEN
CONVERT(DATETIME, LEFT(d, 23))
WHEN d LIKE '[0-9][0-9]-%' THEN
CONVERT(DATETIME, CONVERT(CHAR(8),
CONVERT(DATETIME,REPLACE(LEFT(d,9),' ','-'),6),112)
+ ' ' + REPLACE(SUBSTRING(d,11,8),'.',':')
+ ' ' + RIGHT(RTRIM(d),2))
END
FROM #x;
The conversion for 126 requires no spaces ... I've got it to work like this:
declare #T varchar(50)
declare #dt datetime
set #T = '2006-04-25T15:50:59.997'
set #dt = convert(datetime,#t,126)
select #T, #dt
select convert(datetime,left('2006-04-25T15:50:59.997000 PM',23))
or
select convert(datetime,left(capturedatetime,23))
If you use cast, you do not even need to supply a format. Code snippet below tested on SQL 2012 Developer version.
declare #var_string varchar(50) = '2006-04-25T15:50:59.997';
declare #var_datetime datetime = cast(#var_string as datetime);
select #var_string as my_string, #var_datetime as my_variable;

Convert varchar into datetime in SQL Server

How do I convert a string of format mmddyyyy into datetime in SQL Server 2008?
My target column is in DateTime
I have tried with Convert and most of the Date style values however I get an error message:
'The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.'
OP wants mmddyy and a plain convert will not work for that:
select convert(datetime,'12312009')
Msg 242, Level 16, State 3, Line 1
The conversion of a char data type to a datetime data type resulted in
an out-of-range datetime value
so try this:
DECLARE #Date char(8)
set #Date='12312009'
SELECT CONVERT(datetime,RIGHT(#Date,4)+LEFT(#Date,2)+SUBSTRING(#Date,3,2))
OUTPUT:
-----------------------
2009-12-31 00:00:00.000
(1 row(s) affected)
SQL Server can implicitly cast strings in the form of 'YYYYMMDD' to a datetime - all other strings must be explicitly cast. here are two quick code blocks which will do the conversion from the form you are talking about:
version 1 uses unit variables:
BEGIN
DECLARE #input VARCHAR(8), #mon CHAR(2),
#day char(2), #year char(4), #output DATETIME
SET #input = '10022009' --today's date
SELECT #mon = LEFT(#input, 2), #day = SUBSTRING(#input, 3,2), #year = RIGHT(#input,4)
SELECT #output = #year+#mon+#day
SELECT #output
END
version 2 does not use unit variables:
BEGIN
DECLARE #input CHAR(8), #output DATETIME
SET #input = '10022009' --today's date
SELECT #output = RIGHT(#input,4) + SUBSTRING(#input, 3,2) + LEFT(#input, 2)
SELECT #output
END
Both cases rely on sql server's ability to do that implicit conversion.
Likely you have bad data that cannot convert. Dates should never be stored in varchar becasue it will allow dates such as ASAP or 02/30/2009. Use the isdate() function on your data to find the records which can't convert.
OK I tested with known good data and still got the message. You need to convert to a different format becasue it does not know if 12302009 is mmddyyyy or ddmmyyyy. The format of yyyymmdd is not ambiguous and SQL Server will convert it correctly
I got this to work:
cast( right(#date,4) + left(#date,4) as datetime)
You will still get an error message though if you have any that are in a non-standard format like '112009' or some text value or a true out of range date.
I found this helpful for my conversion, without string manipulation. https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql
CONVERT(VARCHAR(23), #lastUploadEndDate, 121)
yyyy-mm-dd hh:mi:ss.mmm(24h) was the format I needed.
Convert would be the normal answer, but the format is not a recognised format for the converter, mm/dd/yyyy could be converted using convert(datetime,yourdatestring,101) but you do not have that format so it fails.
The problem is the format being non-standard, you will have to manipulate it to a standard the convert can understand from those available.
Hacked together, if you can guarentee the format
declare #date char(8)
set #date = '12312009'
select convert(datetime, substring(#date,5,4) + substring(#date,1,2) + substring(#date,3,2),112)
Look at CAST / CONVERT in BOL that should be a start.
If your target column is datetime you don't need to convert it, SQL will do it for you.
Otherwise
CONVERT(datetime, '20090101')
Should do it.
This is a link that should help as well:
I'd use STUFF to insert dividing chars and then use CONVERT with the appropriate style. Something like this:
DECLARE #dt VARCHAR(100)='111290';
SELECT CONVERT(DATETIME,STUFF(STUFF(#dt,3,0,'/'),6,0,'/'),3)
First you use two times STUFF to get 11/12/90 instead of 111290, than you use the 3 to convert this to datetime (or any other fitting format: use . for german, - for british...) More details on CAST and CONVERT
Best was, to store date and time values properly.
This should be either "universal unseparated format" yyyyMMdd
or (especially within XML) it should be ISO8601: yyyy-MM-dd or yyyy-MM-ddThh:mm:ss More details on ISO8601
Any culture specific format will lead into troubles sooner or later...
use Try_Convert:Returns a value cast to the specified data type if the cast succeeds; otherwise, returns null.
DECLARE #DateString VARCHAR(10) ='20160805'
SELECT TRY_CONVERT(DATETIME,#DateString)
SET #DateString ='Invalid Date'
SELECT TRY_CONVERT(DATETIME,#DateString)
Link:MSDN TRY_CONVERT (Transact-SQL)
I had luck with something similar:
Convert(DATETIME, CONVERT(VARCHAR(2), #Month) + '/' + CONVERT(VARCHAR(2), #Day)
+ '/' + CONVERT(VARCHAR(4), #Year))
The root cause of this issue can be in the regional settings - DB waiting for YYYY-MM-DD while an app sents, for example, DD-MM-YYYY (Russian locale format) as it was in my case. All I did - change locale format from Russian to English (United States) and voilĂ .
This seems the easiest way..
SELECT REPLACE(CONVERT(CHAR(10), GETDATE(), 110),'-','')
SQL standard dates while inserting or updating Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.
So if you are inserting/Updating below 1/1/1753 you will get this error.
DECLARE #d char(8)
SET #d = '06082020' /* MMDDYYYY means June 8. 2020 */
SELECT CAST(FORMAT (CAST (#d AS INT), '##/##/####') as DATETIME)
Result returned is the original date string in #d as a DateTime.