Read nvarchar data into DateTimeOffset in T-SQL - sql

I have nvarchar values with the following format
10:27:32.357 +03 Aug 31 2022
How to convert those to DatetimeOffset variables in T-SQL?
I have to deal with huge amounts of data, so I want to avoid rebuild the value as segments and then use DATETIMEOFFSETFROMPARTS.

Based on the one example we have, and assuming your dates are always in the format hh:mm:ss.nnn [+-]tzoffset MMM dd yyyy (which is honestly an awful format) you could do something like this:
DECLARE #BadDateString nvarchar(50) = N'10:27:32.357 +03 Aug 31 2022';
SELECT CONVERT(datetimeoffset(3),CONVERT(varchar(10),CONVERT(date,RIGHT(#BadDateString,11)),120)+'T'+REPLACE(LEFT(#BadDateString,16),' ','') + ':00')
I strongly suggest, however, that you fix the problem by having the application that is sending this data in this format as a strongly typed date and time (datetimeoffset) value in the first place; T-SQL's forté isn't strong at string manipulations like like.

Related

Getting Conversion failed error when converting date and/or time from character string

In my table values are saved as Thursday November 12, 2020 07:01. I want to convert those values to the date time. This is the query which I wrote.
select
convert(varchar(200), replace(replace(replace(replace(replace(replace(replace(publishedon,'Monday',''),'Saturday',''),'Sunday',''),'Tuesday',''),'Wednesday',''),'Thursday',''),'Friday',''))
from py_EconNext
Once I removed the days from the values, I can get values as November 12, 2020 11:04. After that I try to convert it to datetime. When converting this to the datetime, I’m getting the error
Conversion failed when converting date and/or time from character
string.
But when I run select as below
select convert(datetime,convert(varchar(200),(' November 12, 2020 11:04')))
I can get the values as 2020-11-12 11:04:00.000 without any error.
Table column datatype - varchar(200)
The problem is that you have inconsistent styles of a date, that is (foolishly) being stored as a varchar. This is why storing dates as a varchar is always a bad idea. The real solution is fix your design.
You can get around this with a couple of TRY_CONVERTs, provided that your style is always mon dd, yyyy hh:mi:ss or day, mon dd, yyyy hh:mi:ss. I am using the style code 109 to be explicit on the style code mon dd yyyy hh:mi:ss:mmmAM (or PM) (note that it is happy to accept a 24 clock too):
SELECT ISNULL(TRY_CONVERT(datetime,V.YourString,109),TRY_CONVERT(datetime,STUFF(V.YourString,1,CHARINDEX(' ',V.YourString),''),109))
FROM (VALUES('Thursday November 12, 2020 17:01'),('Thursday November 12, 2020 07:01'),('November 12, 2020 07:01'))V(YourString)
Rather than converting into a VARCHAR (which it already is), it would make more sense to convert straight into a DATETIME.
As well as that, there is no need to have all the embedded REPLACE statements - just take all of the text from the string after the first space.
Try this code:
CREATE TABLE #py_EconNext (publishedon VARCHAR(200));
INSERT INTO #py_econNext VALUES ('Thursday November 12, 2020 07:01');
select convert(datetime, RIGHT(publishedon, LEN(publishedon) - CHARINDEX(' ', publishedon)))
from #py_EconNext;
DROP TABLE #py_EconNext;
Output:
2020-11-12 07:01:00.000
Edit following suggestion to use TRY_CONVERT
Following a helpful comment suggesting the use of TRY_CONVERT in place of CONVERT, please see the equivalent code using the other function:
CREATE TABLE #py_EconNext (publishedon VARCHAR(200));
INSERT INTO #py_econNext VALUES ('Thursday November 12, 2020 07:01'),('Not valid');
select try_convert(datetime, RIGHT(publishedon, LEN(publishedon) - CHARINDEX(' ', publishedon)))
from #py_EconNext
DROP TABLE #py_EconNext;
Output:
2020-11-12 07:01:00.000
NULL
This benefits from not causing an error if the conversion fails, but rather returns NULL.
My personal view is that a data conversion failure is an error and should be treated as such, but the desired solution would ultimately be dictated by the use case OP is outlining.
Storing datetime in varchar column is bad idea.Use appropriate column type when storing data.
Considering your question i assume there is invalid characters included in data like CR, LF or CR+LF.
try to replace them by
SELECT REPLACE(REPLACE(#str, CHAR(13), ''), CHAR(10), '')

SQL Server Convert 01 December 2016 to date

How can one convert the string "01 December 2016" to a date type in SQL Server?
CONVERT(date, '01 December 2016', 106)
Expected date outcome "01 Dec 2016"
If 2012+ you can use Format()
Select Format(convert(date,'01 December 2016'),'dd MMM yyyy')
Returns
01 Dec 2016
It is very dangerous to work with culture specific date/time formats and it is even worse to work with language and culture specific formats...
If ever possible store date/time values in appropriate types!
In my (german) system a direct cast or convert would break due to "December", which is "Dezember" in Germany. Have a look at this:
SET LANGUAGE English; --try the same with "German"
DECLARE #d VARCHAR(100)='01 December 2016';
SELECT CONVERT(VARCHAR(11),CONVERT(DATE,#d,106),106);
The result
01 Dec 2016
One should never rely on implicit conversions: Call CONVERT with the third parameter in any case!
The third parameter 106 tells SQL Server the date's format (how to parse it). The first CONVERTSs target type is DATE. This - now properly represented! - date can be converted again to VARCHAR(11) with 106 as third parameter now specifying the output format.
For deeper insight in language specific date parts you can run this query:
SELECT * FROM sys.syslanguages;
btw: If you are using SQL Server 2012+ you should call FORMAT() as pointed out by John Cappelletti

SQL Server 2012 convert datetime data from varchar to Date portion

Have researched a lot, both on this site, and others, but still don't have a valid solution. I have a column of varchar datatype, it contains DateTime data. I need to store only the Date portion in a Date type column. Tried different ways of Cast, Convert, and other functions, but still haven't been able to make it work.
Basically I want to convert this
Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)
to
04/26/2016
Assuming your Day and Month part is always 3 characters long this can be done simply as this:
DECLARE #d VARCHAR(100)='Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)';
SELECT CONVERT(DATE,SUBSTRING(#d,4,12),109);
If this was to easy one would have to find the blank(s) with CHARINDEX, but I don't think so...
The format code 109 means mon dd yyyy hh:mi:ss:mmmAM (or PM) Details here.
And be aware that formats containing language depending parts are directly sent by the devil to create never ending pain... This will not work on a server with a different language setting!
Declare #String varchar(max) = 'Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)'
Select cast(Substring(#String,12,4)+Substring(#String,4,7) as date)
Returns
2016-04-26
Okay a few things here you have a field that looks to be psuedo ISO 8601 but is not the standard. The first question will be: "Where does this come from?" Typically you don't have the 'Tue' or 'GMT' or '(CEST)' in a standard and the offset from Greenwich Meantime is in the format (+/-)##:## NOT (+/-)####. SQL and many other formats can easily accept a standardized string in the ISO 8601 format. Good brief here: https://www.w3.org/TR/NOTE-datetime
That being said you can easily get what you want with a little know how:
DECLARE
#S VARCHAR(128) = 'Tue Apr 26 2016 13:54:53 GMT+0200 (CEST)'
, #Valid VARCHAR(128)
--Legitimate ISO 8601 string:
SELECT #Valid = RTRIM(LTRIM(REPLACE(STUFF(STUFF(#S, 1, 4, ''), LEN(#S)-12, 12, ':00'), 'GMT', '')))
SELECT #Valid
--Legitimate DateTimeOffset
SELECT CAST(#Valid AS DATETIMEOFFSET)
--Now that I have a legimiate DateTimeOffset I can downconvert easily
SELECT CAST(CAST(#Valid AS DATETIMEOFFSET) AS DATE)
--AND... Now that I have a legimate Date I can format it many different ways
SELECT CONVERT(VARCHAR, CAST(CAST(#Valid AS DATETIMEOFFSET) AS DATE), 101)
The real thing to realize here is there is magical conversion of DateTime using the convert function. But you may be wondering 'what if I want it to look different?'. Try this page:
http://www.sql-server-helper.com/tips/date-formats.aspx
I would be leery though of just finding the placement of were things appear to be coming from a string even though I can parse your example. If you are getting things not following a standard you should know why. The main reason being you may be able to get this to work for a specific instance but not be able to repeat this pattern over and over.

Convert dd-mm-yyyy to mm/dd/yyyy

I have a varchar(200) column called Submit_Date and I am trying to convert it to MM/DD/YYYY format. When I do that I get the following error:
Msg 242, Level 16, State 3, Line 1The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Sample Data of the table is:
Submit_Date
-----------------------
27-09-2013 16:15:00 CST
30-09-2013 16:30:24 CST
27-09-2013 10:03:46 CST
I tried the following:
Select Convert(datetime,Submit_date,101) from dbo.Tickets
You've committed about 15 cardinal sins about date/time here. First, the quick answer:
DECLARE #x VARCHAR(200);
SELECT #x = '27-09-2013 16:15:00 CST'
SELECT CONVERT(CHAR(10),CONVERT(DATETIME,LEFT(#x,10),105),101);
Next:
Why on earth are you storing date/time data in a varchar(200) column? You are aware that anyone can insert values like '09-27-2013' or '465-32-207floob' in there, right? If you need time zone information you can look at the DATETIMEOFFSET data type (but note that it is not DST-aware).
Why are you storing a regional format like dd-mm-yyyy? If the first value were 07-11-2013 I'd have to guess if you meant July 11 or November 7. If you're not going to do it right and use a proper date/time data type, why use a string format that makes people guess? You are much better off with a format that is unambiguous, such as yyyy-mm-ddThh:mm:ssZ.
Similarly, why are you outputting a different regional format like mm/dd/yyyy? If you output '05/06/2013' are you 100% confident that everyone in your audience will know you meant May 6 and not June 5? Your output should be unambiguous as well. If you absolutely must format in some regional and ambiguous format, use the string formatting capabilities of your client. For example, C# has .ToString() and .Format() which are much more powerful and efficient in presenting dates with string formats that T-SQL will ever be.
try the following SQL query to achieve the expected result:
SELECT convert(varchar, convert(date, '27-09-2013 16:15:00', 105), 101)

SELECT CONVERT(VARCHAR(10), GETDATE(), 110) what is the meaning of 110 here?

When we convert or cast date in sql, see below sql code
SELECT CONVERT(VARCHAR(10), GETDATE(), 110) AS [MM-DD-YYYY]
it works fine, I just want to know the meaning of 110 in above code. what it does actually, sometimes we use 102, 112 etc. what is the use of that number.
That number indicates Date and Time Styles
You need to look at CAST and CONVERT (Transact-SQL). Here you can find the meaning of all these Date and Time Styles.
Styles with century (e.g. 100, 101 etc) means year will come in yyyy format. While styles without century (e.g. 1,7,10) means year will come in yy format.
You can also refer to SQL Server Date Formats. Here you can find all date formats with examples.
110 is the Style value for the date format.
TSQL Date and Time Styles
When you convert expressions from one type to another, in many cases there will be a need within a stored procedure or other routine to convert data from a datetime type to a varchar type. The Convert function is used for such things. The CONVERT() function can be used to display date/time data in various formats.
Syntax
CONVERT(data_type(length), expression, style)
Style - style values for datetime or smalldatetime conversion to character data. Add 100 to a style value to get a four-place year that includes the century (yyyy).
Example 1
take a style value 108 which defines the following format:
hh:mm:ss
Now use the above style in the following query:
select convert(varchar(20),GETDATE(),108)
Example 2
we use the style value 107 which defines the following format:
Mon dd, yy
Now use that style in the following query:
select convert(varchar(20),GETDATE(),107)
Similarly
style-106 for Day,Month,Year (26 Sep 2013)
style-6 for Day, Month, Year (26 Sep 13)
style-113 for Day,Month,Year, Timestamp (26 Sep 2013 14:11:53:300)
10 = mm-dd-yy
110 = mm-dd-yyyy
SQL Server CONVERT() Function