I am trying to convert a date to datetime but am getting errors. The datatype I'm converting from is (float,null) and I'd like to convert it to DATETIME.
The first line of this code works fine, but I get this error on the second line:
Arithmetic overflow error converting expression to data type datetime.
CAST(CAST( rnwl_efctv_dt AS INT) AS char(8)),
CAST(CAST( rnwl_efctv_dt AS INT) AS DATETIME),
you need to convert to char first because converting to int adds those days to 1900-01-01
select CONVERT (datetime,convert(char(8),rnwl_efctv_dt ))
here are some examples
select CONVERT (datetime,5)
1900-01-06 00:00:00.000
select CONVERT (datetime,20100101)
blows up, because you can't add 20100101 days to 1900-01-01..you go above the limit
convert to char first
declare #i int
select #i = 20100101
select CONVERT (datetime,convert(char(8),#i))
Try this:
select CONVERT(datetime, convert(varchar(10), 20120103))
use a where clause on that field to ignore nulls and zero values
update
table
set
BDOS= CONVERT(datetime, convert(char(8), field))
where
isnull(field,0)<>0
A simpler, and possibly faster solution is to use DATEFROMPARTS and a bit of arithmetic.
DECLARE #v bigint = 20220623;
SELECT DATEFROMPARTS(#v / 10000, #v / 100 % 100, #v % 100);
Result
2022-06-23
db<>fiddle
Convert(VARCHAR(10), CAST(CONVERT(char(8), "Replace with you date") as date), 101) "Your alias"
Related
I am trying to convert INT (YYYYMM) value to DATE.
I have read articles which mention that converts from char to date format. So I am curious to know - which of the foll. is a good approach?
Example:
DECLARE #PERIOD INT ='201806'
SELECT CAST(CONCAT(#Period,'01') AS DATE) SQLCAST1
,CAST(CAST(#Period AS varchar(6))+'01' AS DATE) SQLCAST2
Which is the ideal approach and why? Do we have other better approach?
I am not a fan of implicit data type conversions, so I would phrase the first as:
select convert(date, convert(varchar(6), #PERIOD ) + '01')
Or use datefromparts() which is a built-in function for constructing dates:
select datefromparts( #PERIOD / 100, #PERIOD % 100, 1)
Apparently concat is the most efficient method.
https://raresql.com/2013/03/12/sql-server-string-concatenation-faster-method/
Cast also appears to be the most efficient method for parsing a standard date string (see the try_cast times for DateTime)
SQL - Convert INT to Date
Your first method is most efficient.
Here is another method, First you have to convert to char then convert to date time,
declare #intValue int
select #intValue = 201907
select convert(date, convert(varchar(6), #intValue ) + '01')
String:
'01/04/2019 01:50:31.230000000'
Expected result:
01/04/2019 01:50:31.230
as a DATETIME.
Query used:
SELECT CONVERT(DATETIME, '01/04/2019 01:50:31.230000000', 113)
Converting that string, which is in the 103 format, would work if it didn't have the last 6 zero's.
So a SUBSTRING or LEFT could be used to keep only 23 characters.
And then convert it to a DATETIME.
But that string, can be converted just fine to a DATETIME2.
Since a DATETIME2 is more accurate.
And a DATETIME2 can be simply casted or converted to a DATETIME.
Note that DATETIME isn't stored with a format in the table.
The way it's displayed is a setting.
However, you can FORMAT a DATETIME back to a string in the specific format you need. (starting with SQL Server 2012)
Example snippet:
select
col as col_input_string,
CAST(CONVERT(datetime2, col, 103) AS datetime) as col_as_datetime,
FORMAT(CONVERT(datetime2, col, 103), 'dd/MM/yyyy HH:mm:ss.fff') as col_as_formatted_string
from (values
('01/04/2019 01:50:31.230000000')
,('31/12/2018 13:33:44.123456789')
) q(col);
Result:
col_input_string col_as_datetime col_as_formatted_string
01/04/2019 01:50:31.230000000 2019-04-01 01:50:31.230 01/04/2019 01:50:31.230
31/12/2018 13:33:44.123456789 2018-12-31 13:33:44.123 31/12/2018 13:33:44.123
The code you want is:
SELECT CONVERT(datetime,LEFT('01/04/2019 01:50:31.230000000',23),103);
You need to use LEFT as datetime is only accurate to 1/300 of a second; thus you need to trim off the accuracy that can't be used.
Try to use
declare #vardate varchar(50) = '01/04/2019 01:50:31.230000000'
declare #date datetime =convert(date, left(#vardate,23), 103)
declare #time time = convert(time, substring(#vardate,12,12), 14)
select DATEADD(DAY, DATEDIFF(DAY, #time, #date), CAST(#time AS DATETIME)) AS Result
if that does not work check different convert formats.
I am trying to convert a single integer which represents the hour value into a time. I've tried using cast but this converts the value to a date
cast(datepart(hh,tstart) as datetime) as test
I've also tried casting it as a time and the conversion is not allowed.
The numbers I am working with are 7,8,9,10,11,12,13,...,23, 0
The format I would like is convert 7 to 7:00, 23 to 23:00, etc
Thank you
There are many ways to do that:
WITH table_name AS
(
SELECT * FROM (VALUES
(1),(2),(3),(10),(23)
) T(H)
)
SELECT DATEADD(HOUR, H, 0) DateValue,
CONVERT(time, DATEADD(HOUR, H, 0)) TimeValue,
CONVERT(varchar(2), H)+':00' TextValue
FROM table_name T1
I would recomend storing value as TIME datatype.
You can try this:
select cast(dateadd(hour,3,'00:00:00') as time)
which gives result:
03:00:00.0000000
Use your int values in place of 3 in above statement
Use convert datetime to varchar datatype and use case statement
DECLARE #date datetime ='2016-05-01 10:00:000'
SELECT CASE cast(DATEPART(hh,#date)as varchar(10))
WHEN '10'then '10:00'
WHEN '11'then '11:00'
WHEN '12'then '12:00'
.
.
.
WHEN '23' then '23:00'
END 'Hourpart'
You can concatenate a minute to the time and cast it to time
select cast(concat(20,':00') as time(7)) as 'time'
If you wanted to display like 'HH:MM',use the below query.
SELECT CAST(23 AS VARCHAR(50))+':00'
If you wanted to get the result as time format,use the below query.
SELECT CAST(CAST(23 AS VARCHAR(50))+':00:00' AS TIME)
OR
SELECT CAST(DATEADD(HOUR,23,'00:00:00') as time)
here is the sample output :
Assuming all of your potential values are integers between 1 and 24, I think FORMAT is the simplest way.
FORMAT(tstart*100,'00:00')
I have a column abc varchar(100) with data like 2011-09-26 16:36:57.810000
I want to convert this column to DATETIME...
But doing a
Convert(DATETIME, abc,120)
is giving this error:
Conversion failed when converting date and/or time from character string.
Can any one please help me convert my varchar format to datetime in SQL Server 2008?
Thanks in advance
You can use style 121 but you can have only 3 digits for milliseconds (i.e yyyy-mm-dd hh:mi:ss.mmm(24h)) format.
declare #abc varchar(100)='2011-09-26 16:36:57.810'
select convert(datetime,#abc,121)
So you can sort it out by limiting the varchar field to 23 characters before converting as:
declare #abc varchar(100)='2011-09-26 16:36:57.810000'
select convert(datetime,convert(varchar(23),#abc),121)
Or use the Left() function to get first 23 characters as:
select convert(datetime,left(#abc,23),121)
Try to avoid storing date as string.
In case you need 6 digits precision use DATETIME2
SELECT CONVERT(DATETIME2, '2016-08-09T08:08:50.358000', 126) as MSSQLDateTime2
SELECT CONVERT(DATETIME, '2016-08-09T08:08:50.358', 126) as MSSQLDateTime
SQL Server only supports 3 decimal places for milliseconds, so the following will work:
Convert(DATETIME, SUBSTRING(abc, 0, 24) ,120)
Based on GBrian's answer, I came up with:
CONVERT(DATETIME, CONVERT(DATETIME2, abc, 126))
I haven't benchmarked how this stacks up against the substring-based solutions.
Assuming we have the following string variables:
DECLARE #d VARCHAR(100) = '2020-04-06T04:35:07.9490051Z' -- 7 digits nanoseconds
DECLARE #d1 VARCHAR(100) = '2020-04-05T15:00:00Z' -- simple: without nanoseconds
I came up to the solution using CAST operator:
SELECT CAST(LEFT(#d,19) + 'Z' AS DATETIME) -- outputs: 2020-04-06 04:35:07.000
SELECT CAST(LEFT(#d1,19) + 'Z' AS DATETIME) -- outputs: 2020-04-05 15:00:00.000
Using SQL Server 2008, this query works great:
select CAST(CollectionDate as DATE), CAST(CollectionTime as TIME)
from field
Gives me two columns like this:
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
2013-01-25 18:53:00.0000000
.
.
.
I'm trying to combine them into a single datetime using the plus sign, like this:
select CAST(CollectionDate as DATE) + CAST(CollectionTime as TIME)
from field
I've looked on about ten web sites, including answers on this site (like this one), and they all seem to agree that the plus sign should work but I get the error:
Msg 8117, Level 16, State 1, Line 1
Operand data type date is invalid for add operator.
All fields are non-zero and non-null. I've also tried the CONVERT function and tried to cast these results as varchars, same problem. This can't be as hard as I'm making it.
Can somebody tell me why this doesn't work? Thanks for any help.
Assuming the underlying data types are date/time/datetime types:
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), CollectionDate, 112)
+ ' ' + CONVERT(CHAR(8), CollectionTime, 108))
FROM dbo.whatever;
This will convert CollectionDate and CollectionTime to char sequences, combine them, and then convert them to a datetime.
The parameters to CONVERT are data_type, expression and the optional style (see syntax documentation).
The date and time style value 112 converts to an ISO yyyymmdd format. The style value 108 converts to hh:mi:ss format. Evidently both are 8 characters long which is why the data_type is CHAR(8) for both.
The resulting combined char sequence is in format yyyymmdd hh:mi:ss and then converted to a datetime.
The simple solution
SELECT CAST(CollectionDate as DATETIME) + CAST(CollectionTime as DATETIME)
FROM field
An easier solution (tested on SQL Server 2014 SP1 CU6)
Code:
DECLARE #Date date = SYSDATETIME();
DECLARE #Time time(0) = SYSDATETIME();
SELECT CAST(CONCAT(#Date, ' ', #Time) AS datetime2(0));
This would also work given a table with a specific date and a specific time field. I use this method frequently given that we have vendor data that uses date and time in two separate fields.
Cast it to datetime instead:
select CAST(CollectionDate as DATETIME) + CAST(CollectionTime as TIME)
from field
This works on SQL Server 2008 R2.
If for some reason you wanted to make sure the first part doesn't have a time component, first cast the field to date, then back to datetime.
DECLARE #ADate Date, #ATime Time, #ADateTime Datetime
SELECT #ADate = '2010-02-20', #ATime = '18:53:00.0000000'
SET #ADateTime = CAST (
CONVERT(Varchar(10), #ADate, 112) + ' ' +
CONVERT(Varchar(8), #ATime) AS DateTime)
SELECT #ADateTime [A nice datetime :)]
This will render you a valid result.
Solution (1): datetime arithmetic
Given #myDate, which can be anything that can be cast as a DATE, and #myTime, which can be anything that can be cast as a TIME, starting SQL Server 2014+ this works fine and does not involve string manipulation:
CAST(CAST(#myDate as DATE) AS DATETIME) + CAST(CAST(#myTime as TIME) as DATETIME)
You can verify with:
SELECT GETDATE(),
CAST(CAST(GETDATE() as DATE) AS DATETIME) + CAST(CAST(GETDATE() as TIME) as DATETIME)
Solution (2): string manipulation
SELECT GETDATE(),
CONVERT(DATETIME, CONVERT(CHAR(8), GETDATE(), 112) + ' ' + CONVERT(CHAR(8), GETDATE(), 108))
However, solution (1) is not only 2-3x faster than solution (2), it also preserves the microsecond part.
See SQL Fiddle for the solution (1) using date arithmetic vs solution (2) involving string manipulation
Concat date of one column with a time of another column in MySQL.
SELECT CONVERT(concat(CONVERT('dateColumn',DATE),' ',CONVERT('timeColumn', TIME)), DATETIME) AS 'formattedDate' FROM dbs.tableName;
drop table test
create table test(
CollectionDate date NULL,
CollectionTime [time](0) NULL,
CollectionDateTime as (isnull(convert(datetime,CollectionDate)+convert(datetime,CollectionTime),CollectionDate))
-- if CollectionDate is datetime no need to convert it above
)
insert test (CollectionDate, CollectionTime)
values ('2013-12-10', '22:51:19.227'),
('2013-12-10', null),
(null, '22:51:19.227')
select * from test
CollectionDate CollectionTime CollectionDateTime
2013-12-10 22:51:19 2013-12-10 22:51:19.000
2013-12-10 NULL 2013-12-10 00:00:00.000
NULL 22:51:19 NULL
This works in SQL 2008 and 2012 to produce datetime2:
declare #date date = current_timestamp;
declare #time time = current_timestamp;
select
#date as date
,#time as time
,cast(#date as datetime) + cast(#time as datetime) as datetime
,cast(#time as datetime2) as timeAsDateTime2
,dateadd(dayofyear,datepart(dayofyear,#date) - 1,dateadd(year,datepart(year,#date) - 1900,cast(#time as datetime2))) as datetime2;
dealing with dates, dateadd must be used for precision
declare #a DATE = getdate()
declare #b time(7) = getdate()
select #b, #A, GETDATE(), DATEADD(day, DATEDIFF(day, 0, #a), cast(#b as datetime2(0)))
I am using SQL Server 2016 and both myDate and myTime fields are strings. The below tsql statement worked in concatenating them into datetime
select cast((myDate + ' ' + myTime) as datetime) from myTable
SELECT CONVERT(DATETIME, CONVERT(CHAR(8), date, 112) + ' ' + CONVERT(CHAR(8), time, 108))
FROM tablename