How to convert custom string to Date in SQL Server - sql

How to convert yyyyMMddhh (2017092018) string to Date in SQL Server 2012?
Is it possible to do without using T-SQL to put the sentence into the INSERT clause?
INSERT INTO [dbo].[Table](SomeColumn)
VALUES (CONVERT(DATETIME, '2017092018', 'yyyyMMddhh'));

Example
Declare #S varchar(50)='2017092018'
Select convert(datetime,left(#S,8)) + convert(datetime,right(#S,2)+':00')
Returns
2017-09-20 18:00:00.000
If 2012+, I would suggest try_convert() just in case you have some unexpected values.

Alternate approach using STUFF:
DECLARE #val VARCHAR(25) = '2017092018';
SELECT CONVERT(DATETIME,STUFF(#val, 9, 0, ' ') + ':00')
This adds a space before the hour, then adds :00 for the minute value.

Here is yet another approach to this. It is similar to what John Cappelletti posted.
Declare #S varchar(50)='2017092018'
Select dateadd(hour, convert(int, right(#s, 2)), left(#s, 8))

You could use DATETIMEFROMPARTS:
DECLARE #d NVARCHAR(10)='2017092018';
SELECT DATETIMEFROMPARTS(LEFT(#d,4),SUBSTRING(#d,5,2),SUBSTRING(#d,7,2),RIGHT(#d,2),0,0,0 ) ;
Rextester Demo
EDIT:
Another option:
DECLARE #S varchar(10)='2017092018'
SELECT CAST(LEFT(#s, 8) AS DATETIME) + RIGHT(#s,2)/24.0;
Rextester Demo2

Related

Formatting Date in sql

Just have an sql query that has a date in the format:
"2018-05-31"
Need to convert it to:
"May-18"
You can use Format function
Select format(getdate(), 'MMM-yyyy')
Try this:
SELECT LEFT(DATENAME(MONTH,GETDATE()),3) + '-' + RIGHT('00' + CAST(YEAR(GETDATE()) AS VARCHAR),2)
SELECT FORMAT(GETDATE(),'MMM yy')
you can try below way
Declare #Date DateTime = '2018-05-31'
Select Format(#Date, N'MMM-yy')
http://sqlfiddle.com/#!18/433d6/194
FORMAT can be very slow. This looks a little less intuative, however, if you have a large dataset, will probably be much quicker:
SELECT STUFF(STUFF(CONVERT(varchar(11),GETDATE(),13),1,3,''),4,3,'-');
This here could work:
declare #date date = '2018-05-31'
select *, FORMAT(DATEFROMPARTS(1900, right(YearMonthKey,2), 1), 'MMMM', 'en-US') +'-'+ substring(YearMonthKey,3,2) as MonthYearName from (
select LEFT(CAST(CONVERT(VARCHAR(8), #date, 112) AS INT),6) as YearMonthKey
)x
I would use convert() with style code 6 :
select replace(substring(convert(varchar(12), datecol, 6), 4, 6), ' ', '-')
You can change the way that a date or timestamp column is display at any time by altering your session to re-set nls_date_format. This will work in SQL*Plus or PL/SQL:
alter session set nls_date_format = 'MON-YY';

convert string to both date and time

I have a data where date and time comes up in yyyymmdd_time (20161012_1528) format.
I want to convert it to date time in SQL Server DB as 2016-10-12 15:28:00:00
is there any straight forward way to do this.or have to create a custom function?
Declare #String varchar(25) = '20161012_1528'
Select cast(left(#String,8)+' '+Stuff(right(#String,4),3,0,':') as datetime)
Or
Select cast(Stuff(Replace(#String,'_',' '),12,0,':') as datetime)
Returns
2016-10-12 15:28:00.000
Please try following method,
It requires a few datetime and convertion functions to be used
declare #dt datetime
declare #str varchar(40) = '20161012_1528'
select #dt =
DATEADD(MI, CAST(right(#str,2) as int),
DATEADD(hh, cast(SUBSTRING(#str,10,2) as int),
CONVERT(datetime, left(#str,8))
)
)
select #dt
The closest I could find was datetime format 112 which does not account for the "_hhmm". I would highly recommend just placing the convert into your T-SQL as the optimizer does not handle UDFs very well.
The T-SQL looks like:
DECLARE #datetimestring nvarchar(max) = '20161012_1528'
SELECT
dateadd(
minute,convert(
int,substring(
#datetimestring,charindex(
'_',#datetimestring
)+3,2
)
),dateadd(
hour,convert(
int,substring(
#datetimestring,charindex(
'_',#datetimestring
)+1,2
)
),convert(
datetime, substring(
#datetimestring,0,charindex(
'_',#datetimestring
)
), 112
)
)
)
The other option is to format the string to the expected date format which is shorter.
SELECT
convert(
datetime,replace(
stuff(
stuff(
stuff(
#datetimestring,5,0,'-'
),8,0,'-'
),14,0,':'
),'_',' '
)
)

SQL Date/Time Format

How to convert date/time from 20150323153528 to 2015-03-23 15:35:28.000. I need this to filter based on the getdate(). Thanks in advance.
Select * from table
Where 20150323153528 > GETDATE() - 7
Statement to convert date to your requirement
DECLARE #Date varchar(20) = '20150323153528'
Select * from table Where
CONVERT(DATETIME, CONVERT(CHAR(8), #Date), 121) + ' ' + stuff(stuff(right('000000' + cast(#Date as varchar),6),5,0,':'),3,0,':') as DATETIME > GETDATE() - 7
In MS SQL you could use
DECLARE #Date varchar(20) = '20150323153528'
Select * from table Where CAST(convert(varchar,#Date) as datetime) > GETDATE() - 7
Please read this page.
SELECT convert(varchar, getdate(), 120) — yyyy-mm-dd hh:mm:ss(24h)
Note: I assume this is a Microsoft SQL Server environment using T-SQL:
The formatting of date / datetime values is not a concern of T-SQL. You should do that in your presentation-layer (i.e. your frontend code).
If you have date/time values represented as integers of the form 20150323153528 then you cannot use them in T-SQL. You need to convert them to strings (preferably in ISO-8601 format) for SQL Server to successfully internally convert them to datetime (or datetimeoffset) values which can then be compared with other datetime values.
I suggest performing the conversion in your application code before you send it to SQL, as a datetime-typed parameter value, like so:
Int32 weirdDateValue = 20150323153528;
String s = weirdDateValue.ToString( CultureInfo.InvariantCulture );
String dtValueAsIso8601 = String.Format("{0}-{1}-{2} {3}:{4}:{5}.{6}",
s.Substring(0, 4), s.Substring(4, 2), s.Substring(6, 2),
s.Substring(8, 2), s.Substring(10, 2), s.Substring(12, 2), s.Substring(14)
);
DateTime dtValue = DateTime.ParseExact( dtValueAsIso8601, "yyyy-MM-dd HH:mm:ss.fff" );
cmd.Parameters.Add("#dtValue", SqlDbType.DateTime).Value = dtValue;
In T-SQL the process is pretty much the same, except using MID - note that MID uses 1-based character indexes instead of 0-based:
DECLARE #input int = 20150323153528
DECLARE #s varchar( 14 ) = CONVERT( #input, nvarchar(14) )
DECLARE #dtStr varchar( 24 ) = MID( #s, 1, 2 ) + '-' + MID( #s, 3, 2 ) + '-' + MID( #s, 5, 2 ) + ' ' + -- etc...
DECLARE #dt datetime = CONVERT( #dtStr, datetime )
SELECT
*
FROM
[table]
WHERE
#dt > GETDATE() - 7
If the integer values are stored in an actual column instead of a parameter you'll need to convert the logic into a scalar UDF which performs the conversion. I strongly suggest you change the table's design to add a strongly-typed datetime column and permanently store the value there, and then drop the datetime-as-int column:
CREATE FUNCTION ConvertIntDateIntoDateTime(#dateAsInt int) RETURNS datetime AS
BEGIN
-- same code as above minus the SELECT statement
RETURN #dt
END
Used in an inner subquery to allow the data to be accessed in WHERE statements, like so:
SELECT
*
FROM
(
SELECT
*,
dbo.ConvertIntDateIntoDateTime( someDateColumn ) AS someDateColumn2
FROM
[table]
) AS FixedTable
WHERE
FixedTable.someDateColumn2 > GETDATE() - 7

T-SQL String to DateTime-conversion

I need to cast string values of the following formats to DateTime:
2042-04
2011-01
Is there an easy way to do this? I've tried CAST AND CONVERT without much luck.
Thanks!
try appending "-01" to the end of it and then doing the cast or convert
declare #S varchar(7)
set #S = '2042-04'
select cast(stuff(#S, 5, 1, '')+'01' as datetime)
YYYYMMDD is a safe format regardless of SET DATEFORMAT. YYYY-MM-DD is not. http://www.sommarskog.se/wishlist.html#YYYYMMDD
SELECT CAST('2011-01-01' AS DATETIME)
SELECT CONVERT(DATE , '2011-01-01')
It seems you need to add a 'day' to the string.
Declare #Table Table
(
ColDateTime Varchar(100)
)
Insert into #Table
Select '2042-04' UNION ALL
Select '2011-01'
Select ColDateTime As VarcharCol,
Cast(
substring(ColDateTime,0,charindex('-',ColDateTime))+substring(ColDateTime,charindex('-',ColDateTime)+1,len(ColDateTime))+'01'
As DateTime) As DateTimeCol
from #Table

How do I create a datetime from a custom format string?

I have datetime values stored in a field as strings. They are stored as strings because that's how they come across the wire and the raw values are used in other places.
For reporting, I want to convert the custom format string (yyyymmddhhmm) to a datetime field in a view. My reports will use the view and work with real datetime values. This will make queries involving date ranges much easier.
How do I perform this conversion? I created the view but can't find a way to convert the string to a datetime.
Thanks!
Update 1 -
Here's the SQL I have so far. When I try to execute, I get a conversion error "Conversion failed when converting datetime from character string."
How do I handle nulls and datetime strings that are missing the time portion (just yyyymmdd)?
SELECT
dbo.PV1_B.PV1_F44_C1 AS ArrivalDT,
cast(substring(dbo.PV1_B.PV1_F44_C1, 1, 8)+' '+substring(dbo.PV1_B.PV1_F44_C1, 9, 2)+':'+substring(dbo.PV1_B.PV1_F44_C1, 11, 2) as datetime) AS ArrDT,
dbo.MSH_A.MSH_F9_C2 AS MessageType,
dbo.PID_A.PID_F3_C1 AS PRC,
dbo.PID_A.PID_F5_C1 AS LastName,
dbo.PID_A.PID_F5_C2 AS FirstName,
dbo.PID_A.PID_F5_C3 AS MiddleInitial,
dbo.PV1_A.PV1_F2_C1 AS Score,
dbo.MSH_A.MessageID AS MessageId
FROM dbo.MSH_A
INNER JOIN dbo.PID_A ON dbo.MSH_A.MessageID = dbo.PID_A.MessageID
INNER JOIN dbo.PV1_A ON dbo.MSH_A.MessageID = dbo.PV1_A.MessageID
INNER JOIN dbo.PV1_B ON dbo.MSH_A.MessageID = dbo.PV1_B.MessageID
According to here, there's no out-of-the-box CONVERT to get from your yyyymmddhhmm format to datetime.
Your strategy will be parsing the string to one of the formats provided on the documentation, then convert it.
declare #S varchar(12)
set #S = '201107062114'
select cast(substring(#S, 1, 8)+' '+substring(#S, 9, 2)+':'+substring(#S, 11, 2) as datetime)
Result:
2011-07-06 21:14:00.000'
This first changes your date string to 20110706 21:14. Date format yyyymmdd as a string is safe to convert to datetime in SQL Server regardless of SET DATEFORMAT setting.
Edit:
declare #T table(S varchar(12))
insert into #T values('201107062114')
insert into #T values('20110706')
insert into #T values(null)
select
case len(S)
when 12 then cast(substring(S, 1, 8)+' '+substring(S, 9, 2)+':'+substring(S, 11, 2) as datetime)
when 8 then cast(S as datetime)
end
from #T
Result:
2011-07-06 21:14:00.000
2011-07-06 00:00:00.000
NULL
You can use CAST or CONVERT.
Example from the site:
G. Using CAST and CONVERT with
datetime data
The following example displays the
current date and time, uses CAST to
change the current date and time to a
character data type, and then uses
CONVERT display the date and time in
the ISO 8901 format.
SELECT
GETDATE() AS UnconvertedDateTime,
CAST(GETDATE() AS nvarchar(30)) AS UsingCast,
CONVERT(nvarchar(30), GETDATE(), 126) AS UsingConvertTo_ISO8601;
GO
Here is the result set.
UnconvertedDateTime UsingCast UsingConvertTo_ISO8601
----------------------- ------------------------------ ------------------------------
2006-04-18 09:58:04.570 Apr 18 2006 9:58AM 2006-04-18T09:58:04.570
(1 row(s) affected)
Generally, you can use this code:
SELECT convert(datetime,'20110706',112)
If you need to force SQL Server to use a custom format string, use the following code:
SET DATEFORMAT ymd
SELECT convert(datetime,'20110706')
A one liner:
declare #datestring varchar(255)
set #datestring = '201102281723'
select convert(datetime, stuff(stuff(#datestring,9,0,' '),12,0,':') , 112 )
Result:
2011-02-28 17:23:00.000
DECLARE #d VARCHAR(12);
SET #d = '201101011235';
SELECT CONVERT(SMALLDATETIME, STUFF(STUFF(#d,9,0,' '),12,0,':'));
Note that by storing date/time data using an inappropriate data type, you cannot prevent bad data from ending up in here. So it might be safer to do this:
WITH x(d) AS
(
SELECT d = '201101011235'
UNION SELECT '201101011267' -- not valid
UNION SELECT NULL -- NULL
UNION SELECT '20110101' -- yyyymmdd only
),
y(d, dt) AS
(
SELECT d,
dt = STUFF(STUFF(LEFT(d+'000000',12),9,0,' '),12,0,':')
FROM x
)
SELECT CONVERT(SMALLDATETIME, dt), ''
FROM y
WHERE ISDATE(dt) = 1 OR d IS NULL
UNION
SELECT NULL, d
FROM y
WHERE ISDATE(dt) = 0 AND d IS NOT NULL;
DECLARE #test varchar(100) = '201104050800'
DECLARE #dt smalldatetime
SELECT #dt = SUBSTRING(#test, 5, 2)
+ '/' + SUBSTRING(#test, 7, 2) + '/'
+ SUBSTRING(#test, 1, 4) + ' ' + SUBSTRING(#test, 9, 2)
+ ':' + SUBSTRING(#test, 11, 2)
SELECT #dt
Output:
2011-04-05 08:00:00