How to convert dates from varchar to datetime2 in SQL Server? - sql

How can I convert these kind of date values from varchar to datetime2?
WITH dates AS (
SELECT '6.7.2012' AS dtm
UNION
SELECT '13.2.2012' AS dtm
UNION
SELECT '3.12.2012' AS dtm
UNION
SELECT '20.11.2012' AS dtm
)
SELECT CAST(dtm as datetime2) FROM dates
;
This results in an error:
Msg 241, Level 16, State 1, Line 6
Conversion failed when converting date and/or time from character string.

Use try_convert instead of cast:
WITH dates AS (
SELECT '6.7.2012' AS dtm
UNION
SELECT '13.2.2012' AS dtm
UNION
SELECT '3.12.2012' AS dtm
UNION
SELECT '20.11.2012' AS dtm
)
SELECT TRY_CONVERT(datetime2, dtm, 104) FROM dates
;
Results:
13.02.2012 00:00:00
20.11.2012 00:00:00
03.12.2012 00:00:00
06.07.2012 00:00:00
Note: try_convert was introduced in 2012 version, for earlier versions you need to use convert, risking an exception if the varchar value can't be converted using the specified style.

Related

Convert ISO-8601 varchar (0000-00-00T00:00:00+00:00) to datetime in SQL

How can I convert 2019-07-01T00:00:00+05:30 to DateTime in SQL?
2019-07-01T00:00:00+05:30 is a varchar field. I need to convert this into DateTime to compare this to a date field.
suggest me a query to Convert (2019-07-01T00:00:00+05:30) into DateTime
Convert To date :
select cast('2019-07-01T00:00:00+05:30' as Date)
Convert To time:
select cast('2019-07-01T00:00:00+05:30' as Time)
Convert To datetime :
select convert(datetime2, '2019-07-01T10:00:30+05:30',0)
Try any of these..
select cast(convert(datetime2, '2019-07-01T10:00:30+05:30',0) as datetime)
select convert(datetime2, '2019-07-01T10:00:30+05:30',0)
One option would be to use a combination of CONVERT on the timestamp without the timezone component, then use TODATETIMEOFFSET with the timezone portion to get the final result:
WITH yourTable AS (
SELECT '2019-07-01T00:00:00+05:30' AS dt
)
SELECT
TODATETIMEOFFSET(CONVERT(datetime, LEFT(dt, 19), 126), RIGHT(dt, 6)) AS output
FROM yourTable;
This outputs:
01/07/2019 00:00:00 +05:30
Demo
Unfortunately, SQL Server truncates the time zone information when converting from datetimeoffset to dateordatetime`. But, you can calculate the offset and add it back in:
select dateadd(minute,
datediff(minute, convert(datetimeoffset, dt), convert(datetime, convert(datetimeoffset, dt))),
convert(datetime, convert(datetimeoffset, dt))
)
from (values ('2019-07-01T00:00:00+05:30')) v(dt);
For your particular timezone, the date at midnight matches the UTC date, so you are safe. I'm on the other side of the world, so this would be a more important consideration in the "western" world ("west" being west of UTC).
The following query will convert the given VARCHAR to DATETIME value:
DECLARE #DateVal AS VARCHAR (30) = '2019-07-01T00:00:00+05:30';
SELECT CAST(REPLACE(SUBSTRING(#DateVal, 0, CHARINDEX('+', #DateVal)), 'T', ' ') AS DATETIME);

Convert date, time stamp to date

I have the data in the following format in varchar form. There are 48 million rows in this format
'2015-09-18 00:00:00.000'
and want to convert it to the following format
'2015-09-18'
Can anyone help me with the code in Oracle
If your column has a timestamp type, you simply need to use to_char to format it properly:
with yourTable(yourDateColumn) as
(
select to_timestamp('2015-09-18 00:00:00.000', 'YYYY-MM-DD HH24:MI:SS.FF') from dual
)
select to_char(yourDateColumn, 'yyyy-mm-dd')
from yourTable
If your column is a string ( and storing dates in string fields is generally a very bad idea) with a fixed format, you simply need a substr:
with yourTable(yourStringColumn) as
(
select '2015-09-18 00:00:00.000' from dual
)
select substr(yourStringColumn, 1, 10)
from yourTable

Conversion failed when converting character string to smalldatetime data type in sql server (Excluding the Static Values)

I have a table storing starttime and endtime.
I Got
Conversion failed when converting character string to smalldatetime
data type.
Error while selecting below query using that table.
select CAST(substring(CONVERT(varchar,convert(smalldatetime,o.StartTime),114), 1,2) as int)
from TimeTable O
In analysis , I found out that Few Records with Starttime as '9:30 PM' causing the error. ( Other Records having '09:30 PM' as start-time). I have excluded '9:30 PM' Records and query executed successfully.
The Problem Here is ,
If I explicitly specify the value in select statement as below,
SELECT CAST(substring(CONVERT(varchar,convert('9:30 PM',o.StartTime),114), 1,2) as int)
I didn't get any error.
But, when I select from the table I got the error. can Anyone help with this?
To what output your are actually looking for?
If you want the values like '9:30 PM' or '09:30 PM' to be converted as Time format, you can go ahead with the below one
SELECT CAST(CONVERT(VARCHAR(8), '9:30 PM', 108)AS TIME)
SELECT CAST(CONVERT(VARCHAR(8), '09:30 PM', 108)AS TIME)
Else if you want it to be stored in datetime or smalldatetime
then this will work for you
SELECT CAST(CONVERT(VARCHAR(8), '9:30 PM', 108)AS DATETIME)
SELECT CAST(CONVERT(VARCHAR(8), '09:30 PM', 108)AS DATETIME)

MSSQL - Convert milliseconds since 1970 to datetime2

Consider the following query (in MSSQL 2008):
SELECT dateModified FROM SomeTable;
This returns floats in javascript format (milliseconds since 1970):
dateModified
============
1301598290687
1071003581343
1311951478593
How can I convert this to a datetime2 right in the select?
Using the formula from #Mikeal Eriksson's answer here.
I would convert the float to a bigint and then create the datetime:
select
DATEADD(MILLISECOND,
cast(dateModified as bigint) % 1000,
DATEADD(SECOND, cast(dateModified as bigint) / 1000, '19700101'))
from sometable
See SQL Fiddle with Demo
Some Oracle example - replace to_date() with eqivalent:
SELECT (1301598290687/60/60/24/1000) as Days
, to_date('01-01-1970','dd-mm-yyyy') as start_date
, to_date('01-01-1970','dd-mm-yyyy')+(1301598290687/60/60/24/1000) as converted_date
FROM dual
/
DAYS START_DATE CONVERTED_DATE
---------------------------------------------------------
15064.7950310995 1/1/1970 3/31/2011 7:04:51 PM
Create dual table:
CREATE TABLE DUAL
(
DUMMY VARCHAR(1)
)
GO
INSERT INTO DUAL (DUMMY)
VALUES ('X')
GO

SQL: Error when trying to filter out all dates older than the current date

I'm using SQL SERVER 2008.
I have a table that stores dates in datetime format (i.e.2012-01-21 15:00:00.000)
I'm trying to filter out all the dates older than "today". So I was attempting to do so by using the query below.
SELECT Date
FROM MyTable
WHERE Date >= GETDATE()
When I run that though, I get the following error.
Conversion failed when converting date and/or time from character string.
Is there something I'm doing wrong? Thanks for the help and let me know if I need to provide more information!
More Information:
[Date] is of type DateTime in MyTable.
I also have a View that simply selects [Date] and does no manipulation
I'm accessing [Date] via the View
It looks like your column is not a DATETIME data type after all. It is probably VARCHAR or similar. If you provide the DDL for the creation of the table, that would allow a more specific answer.
You don't say what locale your in as this will matter. The most likely possibility is that your DATE column isn't a DATETIME. You don't say what locale your in, but (as an example) US and UK datetime formats are treated differently when in reverse format.
UK sees the date as yyyy-dd-mm hh:mm:ss.fff
US sees the date as yyyy-mm-dd hh:mm:ss.fff
For example, this throws an error:
SET LANGUAGE british
GO
SELECT CAST ('1999-01-21 10:11:12.345' AS DATETIME)
GO
However if you change the locale to us_english, it will parse correctly.
If you want to gurantee it's always going to be parsed as yyyy-mm-dd, then you need to be strict and use the full ISO spec by specifying Z between the date and time, e.g.,: 1999-01-21Z10:11:12.345 will parse in the same way in both locales.
Ultimately, you want to change the Date column to a datatype of DATETIME, but you may need to temporarialy change your locale to be able to do this sucessfully; i.e.:
SET LANGUAGE us_english
GO
ALTER TABLE [...]
GO
SET LANGUAGE british
GO
Yet another fun 'gotcha' to watch out for when manipulating date/time data.
Sidenote: no I don't know why the Microsoft think us over in Blighty see the date as yyyy-dd-mm ... I've never encountered this format. Could be inherited from European formats?
First of all you should change this to:
SELECT [Date]
FROM MyTable
WHERE [Date] <= GETDATE()
That type of Column is [Date]????
If your date column is VARCHAR/NVARCHAR you need to convert that value to DATETIME. From your example, the right format should be:
SELECT [Date]
FROM MyTable
WHERE CONVERT(DATETIME,[Date],121) >= GETDATE()
SQL will implicitly convert a varchar to a datatime if you are comparing it to a datetime. The issue you're getting is that there is a record in your table that is not in a datetime format.
GOOD EXAMPLE:
SELECT *
INTO #Temp
FROM
(
SELECT '2010-01-21 15:00:00.000' [Date] UNION
SELECT '2012-01-21 05:30:00.000' [Date] UNION
SELECT '2015-01-21 07:45:00.000' [Date] UNION
SELECT '2020-01-21 11:20:00.000' [Date]
) x
SELECT *
FROM #Temp
WHERE [Date] > GETDATE()
DROP TABLE #Temp
BROKEN EXAMPLE:
SELECT *
INTO #Temp
FROM
(
SELECT '2010-01-21 15:00:00.000' [Date] UNION
SELECT '2012-01-21 05:30:00.000' [Date] UNION
SELECT '2015-01-21 07:45:00.000' [Date] UNION
SELECT 'a2020-01-21 11:20:00.000' [Date]
) x
SELECT *
FROM #Temp
WHERE [Date] > GETDATE()
DROP TABLE #Temp
The 'a' in the last record of the broken example will cause the error your getting.
WORK AROUND
SELECT *
INTO #Temp
FROM
(
SELECT '2010-01-21 15:00:00.000' [Date] UNION
SELECT '2012-01-21 05:30:00.000' [Date] UNION
SELECT '2015-01-21 07:45:00.000' [Date] UNION
SELECT 'a2020-01-21 11:20:00.000' [Date]
) x
SELECT *
FROM
(
SELECT CASE WHEN ISDATE([Date]) = 1 THEN [Date] ELSE '' END [Date]
FROM #Temp
) x
WHERE [Date] > GETDATE()
DROP TABLE #Temp
BETTER OPTION
SELECT *
INTO #Temp
FROM
(
SELECT '2010-01-21 15:00:00.000' [Date] UNION
SELECT '2012-01-21 05:30:00.000' [Date] UNION
SELECT '2015-01-21 07:45:00.000' [Date] UNION
SELECT 'a2020-01-21 11:20:00.000' [Date]
) x
SELECT *
FROM #Temp
WHERE CASE WHEN ISDATE([Date]) = 1 THEN [Date] ELSE '' END > GETDATE()
DROP TABLE #Temp