SQL server v17 : how to convert smalldatetime value to datetime - sql-server

I used following query to insert the data :
CASE(isdate([Date]))
WHEN 1 THEN [date]
WHEN 0 THEN cast(substring([Date],0,5) - 2 as smalldatetime)
ELSE [date] END
Now, datetime column has date in smalldatetime format. How to convert smalldatetime formatted date to datetime format whereas column type is datetime.
Example: For Numeric date 41298 it resulted into 1911-04-21 00:00:00 but actual expected result was 2013-01-26 00:00:00.000

I think you are looking for something like this:
(CASE WHEN ISNUMERIC([Date]) = 1
THEN DATEADD(day, CAST([Date] as int), '1899-12-31')
WHEN iSDATE([Date]) = 1
THEN CAST([date] as smalldatetime)
END)
The value 41298 looks like an Excel formatted date. These start counting from the last day of 1899.

I have tried your given value and it convert to expected result please have a look;
SELECT CAST(CAST(41298 AS smalldatetime) AS DATE) AS Date
SELECT CAST(41298 AS smalldatetime) AS Date
Output:

Another option is DateAdd
Select DateAdd(DAY,41298,'1900-01-01')
Returns
2013-01-26 00:00:00.000

Related

Keep null as empty and convert nvarchar to date

expiredDate nvarchar() column contains data like 22-12-2022 00:00:00 and null.
SELECT ISNULL(CONVERT(Date, expiredDate), '')
FROM tablename
Result for null is default date 1900-01-01 - I want it to be blank or empty.
As the column is getting converted to datetime null is converted to the default date.
Required date should be in yyyy-MM-dd format and null as empty
You may use CONVERT here on the raw date to generate a string, and then COALESCE missing null values into empty string:
SELECT expiredDate,
COALESCE(CONVERT(varchar(10), expiredDate, 120), '') AS expiredDateText
FROM yourTable;
You can try below query.
select case when ISDATE(expiredDate) = 0 then '' else convert(varchar,convert(date,expiredDate)) end as YourColumnName
The ISDATE() function checks whether the input data is a valid date or not. This includes NULL too. It will return Zero (0) if the data is not a date.
If you culture is en-us then by default you will get the date in YYYY-MM-DD format.
You can also use Format function in SQL Server to get the date in your expected format.
More information about format function can be found at below link.
https://learn.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql?view=sql-server-ver15
You've have stumbled upon one of the odd(annoying) quirks in SQL Server where blank string becomes 1900-01-01 when cast to DATE. Your CONVERT() sets the column type to DATE, and then when you do ISNULL, it implicitly casts empty string to DATE. Why it returns 1900-01-01 instead of an error, I have no idea
Example of Empty String to Date Odd Behavior
SELECT CAST('' AS DATE)
--Returns 1900-01-01
Parse Date to Correct DATE data type and Then Format
How I'd recommend this is first converting your NVARCHAR column to the correct DATE data type. Using TRY_CAST allows any invalid dates to not cause the whole query to fail, instead will return NULL. FORMAT() then allows you to format the DATE anyway you like, and ISNULL will change NULL to empty string
DECLARE #YourTable TABLE (ID INT IDENTITY(1,1),expiredDate nvarchar(20))
INSERT INTO #YourTable
VALUES ('22-12-2022 00:00:00'),('31-12-2022 00:00:00'),('02-02-2022 00:00:00'),(NULL)
,('40-02-2022 00:00:00') /*Bad date for testing purposes*/
SELECT *,FormattedExpiredDate = ISNULL(FORMAT(B.ExpiredDateWithCorrectDateType,'yyyy-MM-dd'),'')
FROM #YourTable AS A
/*Format to YYYY-MM-DD (culture agnostic date format) and then use TRY_CAST(). If date is invalid, will return NULL*/
CROSS APPLY (SELECT ExpiredDateWithCorrectDateType = TRY_CAST(SUBSTRING(expiredDate,7,4) + SUBSTRING(expiredDate,4,2) + SUBSTRING(expiredDate,1,2) AS DATE)) AS B
Results:
ID
expiredDate
ExpiredDateWithCorrectDateType
FormattedExpiredDate
1
22-12-2022 00:00:00
2022-12-22
2022-12-22
2
31-12-2022 00:00:00
2022-12-31
2022-12-31
3
02-02-2022 00:00:00
2022-02-02
2022-02-02
4
NULL
NULL
5
40-02-2022 00:00:00
NULL

How to convert date format yyyymmdd to yyyy/mm/dd in SQL Server 2008

I tried some conversions but seems like it's not working. My datatype is a decimal:
date_column
-----------
20140619
20160527
20150601
20131127
20170217
20171204
20160519
My SQL statement:
SELECT
CONVERT(DATE, CONVERT(VARCHAR(10), date_column), 111) AS mydate
FROM
my_table
Results
mydate
-------------
2014-06-19
2016-05-27
2015-06-01
2013-11-27
2017-02-17
2017-12-04
2016-05-19
You currently do this:
decimal -> varchar -> date
which is good, but you are still missing one more step:
decimal -> varchar -> date -> varchar (new format)
Thus, you need:
select CONVERT(varchar(10), CONVERT(date, CONVERT(varchar(8), date_column)), 111) as mydate
from my_table
(What you should actually do is to store the date as a DATE in the first place, but I am aware that this is not always an option for legacy databases.)
You can try either of the below code, based on your preference.
POST SQL SERVER 2012
declare #testDate DATE;
SET #testDate = '20140619'
SELECT FORMAT ( #testDate, 'd', 'zh-cn' ), FORMAT( #testDate, 'yyyy/MM/dd', 'en-US' )
Prior to SQL SERVER 2012
declare #testDate DATE;
SET #testDate = '20140619'
SELECT REPLACE(CAST(CONVERT(date,'20140619',111) AS CHAR(10),'-','/')
SELECT convert(char(10),#testDate,111)
Let me share some of the answers i got:
select format(cast(date_column as date),'yyyy/MM/dd') as mydate
from my_table;
select convert(date,convert(varchar(10), date_column ), 111 ) as mydate
from my_table;
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/53a51068-b802-43e7-baa3-7510d56c5b63/how-to-convert-date-formart-yyyymmdd-to-yyyymmdd-in-sql-server-2008?forum=transactsql
Thank you

How to convert '31/12/18' to type Date with TSQL

I tired this
select CONVERT(DATE, '31/12/18', 103) as rDatum
but I get error:
Conversion failed when converting date and/or time from character string.
What is the right way to convert string which is date with short year to DATE in TSQL?
You were very close...
This is british/french format with a 2-digit year.The format code is 3 (103 is with a 4-digit year)
Try this
select CONVERT(DATE, '31/12/18', 3) as rDatum
Try this
SET DATEFORMAT DMY
INSERT INTO targetTable (rDatum, col2 etc)
SELECT CAST(someDate AS DATE) , col2 etc
FROM sourceTable

Using cast or convert to convert negative int values to datetime in SQL Server

I have some negative integer values which are an offset from the default 1-1-1900 date. I have to get the datetime values from these. How can I do this.
Example:
If I do:
SELECT convert(datetime, 53691) as Calc
OR
SELECT cast(53691 as datetime)
I get: 2047-01-01 00:00:00.000
What I need is that If I do:
SELECT convert(datetime, -53691) as Calc
OR
SELECT cast(-53691 as datetime)
I should get something like:
1753-01-01 00:00:00.000
-53690 would be 1753-01-01. -53691 takes you out of the range of the datetime data type (which doesn't support dates before 1753). Casting -53690 works as your other examples do.

SQL Server remove milliseconds from datetime

select *
from table
where date > '2010-07-20 03:21:52'
which I would expect to not give me any results... EXCEPT I'm getting a record with a datetime of 2010-07-20 03:21:52.577
how can I make the query ignore milliseconds?
You just have to figure out the millisecond part of the date and subtract it out before comparison, like this:
select *
from table
where DATEADD(ms, -DATEPART(ms, date), date) > '2010-07-20 03:21:52'
If you are using SQL Server (starting with 2008), choose one of this:
CONVERT(DATETIME2(0), YourDateField)
LEFT(RTRIM(CONVERT(DATETIMEOFFSET, YourDateField)), 19)
CONVERT(DATETIMEOFFSET(0), YourDateField) -- with the addition of a time zone offset
Try:
SELECT *
FROM table
WHERE datetime >
CONVERT(DATETIME,
CONVERT(VARCHAR(20),
CONVERT(DATETIME, '2010-07-20 03:21:52'), 120))
Or if your date is an actual datetime value:
DECLARE #date DATETIME
SET #date = GETDATE()
SELECT CONVERT(DATETIME, CONVERT(VARCHAR(20), #date, 120))
The conversion to style 120 cuts off the milliseconds...
select * from table
where DATEADD(ms, DATEDIFF(ms, '20000101', date), '20000101') > '2010-07-20 03:21:52'
You'll have to trim milliseconds before comparison, which will be slow over many rows
Do one of these to fix this:
created a computed column with the expressions above to compare against
remove milliseconds on insert/update to avoid the read overhead
If SQL Server 2008, use datetime2(0)
Use CAST with following parameters:
Date
select Cast('2017-10-11 14:38:50.540' as date)
Output: 2017-10-11
Datetime
select Cast('2017-10-11 14:38:50.540' as datetime)
Output: 2017-10-11 14:38:50.540
SmallDatetime
select Cast('2017-10-11 14:38:50.540' as smalldatetime)
Output: 2017-10-11 14:39:00
Note this method rounds to whole minutes (so you lose the seconds as well as the milliseconds)
DatetimeOffset
select Cast('2017-10-11 14:38:50.540' as datetimeoffset)
Output: 2017-10-11 14:38:50.5400000 +00:00
Datetime2
select Cast('2017-10-11 14:38:50.540' as datetime2)
Output: 2017-10-11 14:38:50.5400000
For this particular query, why make expensive function calls for each row when you could just ask for values starting at the next higher second:
select *
from table
where date >= '2010-07-20 03:21:53'
Use 'Smalldatetime' data type
select convert(smalldatetime, getdate())
will fetch
2015-01-08 15:27:00
There's more than one way to do it:
select 1 where datediff(second, '2010-07-20 03:21:52', '2010-07-20 03:21:52.577') >= 0
or
select *
from table
where datediff(second, '2010-07-20 03:21:52', date) >= 0
one less function call, but you have to be beware of overflowing the max integer if the dates are too far apart.
One more way I've set up SQL Server queries to ignore milliseconds when I'm looking for events from a particular second (in a parameter in "YYYY-MM-DD HH:TT:SS" format) using a stored procedure:
WHERE
...[Time_stamp] >= CAST(CONCAT(#YYYYMMDDHHTTSS,'.000') as DateTime) AND
...[Time_stamp] <= CAST(CONCAT(#YYYYMMDDHHTTSS,'.999') as DateTime)
You could use something similar to ignore minutes and seconds too.
Please try this
select substring('12:20:19.8470000',1,(CHARINDEX('.','12:20:19.8470000',1)-1))
(No column name)
12:20:19
I'm very late but I had the same issue a few days ago. None of the solutions above worked or seemed fit. I just needed a timestamp without milliseconds so I converted to a string using Date_Format and then back to a date with Str_To_Date:
STR_TO_DATE(DATE_FORMAT(your-timestamp-here, '%Y-%m-%d %H:%i:%s'),'%Y-%m-%d %H:%i:%s')
Its a little messy but works like a charm.
May be this will help..
SELECT [Datetime] = CAST('20120228' AS smalldatetime)
o/p:
2012-02-28 00:00:00
Review this example:
declare #now datetimeoffset = sysdatetimeoffset();
select #now;
-- 1
select convert(datetimeoffset(0), #now, 120);
-- 2
select convert(datetimeoffset, convert(varchar, #now, 120));
which yields output like the following:
2021-07-30 09:21:37.7000000 +00:00
-- 1
2021-07-30 09:21:38 +00:00
-- 2
2021-07-30 09:21:37.0000000 +00:00
Note that for (1), the result is rounded (up in this case), while for (2) it is truncated.
Therefore, if you want to truncate the milliseconds off a date(time)-type value as per the question, you must use:
declare #myDateTimeValue = <date-time-value>
select cast(convert(varchar, #myDateValue, 120) as <same-type-as-#myDateTimeValue>);

Resources