Convert custom format string to Date - sql

I'm receiving date values(as string) from one of the source system. It is always a 8 char long as shown below. I'm really not sure why they have kept in this format.
15/06-10
07/03-03
28/10-04
10/07-90
05/07-55
But for my application, I need to convert this into a proper date format(i.e. DD-MON-YYYY).
First 2 characters represent Date
Next 2 characters(after /) represent Month
last 2 represent year
In oracle, I can use to_date to achieve this. Something like
select to_date('15/06-10','yy/mm-dd') from dual;
But in SQL Server, I couldn't find such function. Is there a way to achieve this? The closest I have got is
DECLARE #d VARCHAR(100) = '15/06-10';
SELECT DATEFROMPARTS('20'+SUBSTRING(#d,7,2),SUBSTRING(#d,4,2),SUBSTRING(#d,1,2))
I'm not sure if this is the right way. Also It is giving the results only when I hardcode 20 for the year. But i'm getting data from 1950. So I cannot hardcode 19 or 20 Expected output for above sample is
+----------+-------------+
| 15/06-10 | 15-JUN-2010 |
+----------+-------------+
| 07/03-03 | 07-MAR-2003 |
+----------+-------------+
| 28/10-04 | 28-OCT-2004 |
+----------+-------------+
| 10/07-90 | 10-JUL-1990 |
+----------+-------------+
| 05/07-55 | 05-JUL-1955 |
+----------+-------------+

SQL Server does not have a to_date() function. But here is a simpler way to do the conversion you want:
select convert(date, replace('20' + str, '/', '-'))
from (values ('15/06-10'), ('07/03-03'), ('28/10-04')) v(str)
The expression in the select actually changes the format to YYYY-MM-DD, which is trivially converted to a date. However, SQL Server convert()/cast() is relatively smart about recognizing dates in strings.

One option uses datefromparts() and string functions:
select datefromparts(
'20' + left(#d, 2),
substring(#d, 4, 2),
right(#d, 2)
) as dt

Related

replace string with date value

Currently, I have a Derived Column transformation within my package that will look for a NULL value and if it is NULL it will give it a default date with forwarding slashes as seen below
REPLACENULL([date],"2/2/1999")
However, if that field is Not NULL it will have a string date which will look like 20200202. I am wanting to add on to the current expression to where if the field is not null that it replaces 20200202 with 2020-02-02. I would appreciate the help and will rate it highly!
Here's how I would do that in SQL Server.
Note: FORMAT requires SQL Server 2012+
DECLARE #StringDate varchar(20);
-- NON-NULL date.
SET #StringDate = '20200202'
SELECT
ISNULL ( FORMAT( CAST ( #StringDate AS date ), 'yyyy-MM-dd' ), '2/2/1999' ) AS NonNullStringDate;
-- NULL date.
SET #StringDate = NULL;
SELECT
ISNULL ( FORMAT( CAST ( #StringDate AS date ), 'yyyy-MM-dd' ), '2/2/1999' ) AS NullStringDate;
Returns (respectively)
+-------------------+
| NonNullStringDate |
+-------------------+
| 2020-02-02 |
+-------------------+
+----------------+
| NullStringDate |
+----------------+
| 2/2/1999 |
+----------------+
For date formatting consistency, you may want to consider changing 2/2/1999 to 1999-2-2.
First of all, you should use 1999-02-02 as a default value to make sure that all values are stored in the same format. The following expression will convert the date format from yyyyMMdd to yyyy-MM-dd:
REPLACENULL([date],"") == "" ? "1999-02-02" : LEFT([date],4) + "-" + SUBSTRING([date],5,2) + "-" + RIGHT([date],2)

Convert from text(char(50)) to datetime

I'm trying to convert my text column to a datetime. I've tried several things but i keep getting errors. The steps I tried so far:
Convert(datetime, mydate, 103)
The error it gives after performing this query in my system:
'Arithmetic overflow error converting expression to data type datetime'
So I searched on the internet and found several solutions which I tried.
Convert(datetime, convert(char(8), mydate)
and
Cast(cast(mydate as char(8)) as datetime)
The error it gives me after performing these queries: 'conversion failed when converting date and/or time from character string' So I searched for more possible solutions and tried this:
Convert(datetime, convert(char(8), mydate),103)
But this still gives me the same error. I really run out of solutions right now. Does any of you guys maybe know how to fix this problem?
Kind regards and thanks in advance
Here is some sample data:
+----+------------+
| ID | MyDate |
+----+------------+
| 1 | 20170120 |
+----+------------+
| 2 | 19940101 |
+----+------------+
| 3 | 20001220 |
+----+------------+
| 4 | 20171101 |
+----+------------+
The issue is likely with formatting. Do you have an example of the string you're trying to convert to a datetime?
I would advise referring to the "style" parameter in the documentation to ensure it matches the string format that you're passing into the CONVERT function. If you can provide a sample string it will be easier to suggest a working example.
https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017
#miltenburger, I am guessing that #mydate has been stored as integer. That is why it throws the error:
Msg 8115, Level 16, State 2, Line 4
Arithmetic overflow error converting expression to data type datetime
What you need to do is to convert it to varchar first before converting to datetime.
See the mockup below:
DECLARE #mydate INT =20181001
SELECT CONVERT(DATETIME, CAST(#mydate as VARCHAR(20)), 103)
You need to check the database Implied DATEFORMAT set by language
SET LANGUAGE us_english
SELECT CAST('2018-02-25' AS datetime)
SET LANGUAGE british
SELECT CAST('2018-02-25' AS datetime)
You have the wrong format
select convert(datetime, '20000113', 112)

Converting a 5 digit int into time

In a legacy system (SQL Server 2005) I have a column that stores a 5 digit integer (ie 86340) as time. The legacy application shows 86340 as 23:59:00. I am unsure how how to translate that 5 digit integer into a date-time data type using SQL.
SQL Server 2012+ has TIMEFROMPARTS function:
TIMEFROMPARTS ( hour, minute, seconds, fractions, precision )
Returns a time value for the specified time and with the specified precision.
Which is similiar to Excel's TIME:
TIME(hour, minute, second)
Excel version could handle values over 0-60 range:
Minute Required. A number from 0 to 32767 representing the minute. Any value greater than 59 will be converted to hours and minutes.
And SQL counterpart cannot do that.
It looks like that value is simply number of seconds so you could use:
DECLARE #A1 INT = 86340;
SELECT DATEADD(second, #A1,CAST('00:00:00' AS TIME));
DBFiddle Demo
EDIT:
As SQL Server 2005 does not support TIME data type, you could use DATETIME instead and skip date part in application.
DECLARE #A1 INT = 86340;
SELECT DATEADD(second, #A1,CAST('00:00:00' AS DATETIME));
DBFiddle Demo2
Since the value you have is an integer representation of the seconds since midnight, you have a couple of choices in SQL Server 2005. You can either render the value as a VARCHAR, which is readable, you can render it as DATETIME, which appends the date information, or you can maybe pull in a date from another field to get an meaningful DATETIME for your value.
SELECT CONVERT(VARCHAR(12), DATEADD(SECOND, 86340, 0), 114) AS [InVarchar];
+--------------+
| InVarchar |
+--------------+
| 23:59:00:000 |
+--------------+
SELECT DATEADD(SECOND, 86340, 0) AS [InDatetime];
+-------------------------+
| InDatetime |
+-------------------------+
| 1900-01-01 23:59:00.000 |
+-------------------------+
SELECT DATEADD(SECOND, 86340, CAST('2018-09-05' AS DATETIME)) AS [InDatetimeWithDate];
+-------------------------+
| InDatetimeWithDate |
+-------------------------+
| 2018-09-05 23:59:00.000 |
+-------------------------+
USE below query:
SELECT CONVERT(DATETIME, #Column_Name)
FROM Table;

SQL Server datetime in format yyyy-mm-ddThh:mi:ss.mmmZ

For an XML message I need SQL server 2008 R2 to select a set of dates in the following format:
yyyy-mm-ddThh:mi:ss.mmmZ
I searched Google and Stack Overflow a bit and came to the following solution:
SELECT STUFF(CONVERT(VARCHAR(50), CAST(GETDATE() AS DATETIMEOFFSET), 127),24,4,'')
This is working fine except for cases where the milliseconds of the date are "000". In such cases it selects NULL.
Can you please help me to find a solution that also works for dates where the milliseconds are "000"?
You can use the following piece of code to play around with:
declare #timestamps table (
i int,
timestamp datetime
)
insert into #timestamps (i, timestamp)
values
(1, '2017-09-13 01:00:00.003'),
(2, '2017-09-13 02:00:00.333'),
(3, '2017-09-13 03:00:00.000'),
(4, '2017-09-13 04:00:00')
select i, timestamp, STUFF(CONVERT(VARCHAR(50), CAST(timestamp AS DATETIMEOFFSET), 127),24,4,'') from #timestamps
From what I understand, you are using stuff() to get rid of the milliseconds beyond the third decimal place.
Instead you can just specify the precision of datetimeoffset as (3) instead of letting it default to (7):
select
i
, dto3 = convert(varchar(32),convert(datetimeoffset(3),timestamp),127)
, plusZ = convert(varchar(32),timestamp,127)+'Z' --without converting to datetimeoffset
-- /* SQL Server 2012+ */, tsFormat = format(timestamp,'yyyy-MM-ddTHH:mm:ss.fffZ')
from #timestamps
rextester demo: http://rextester.com/VKXBET35937
returns:
+---+--------------------------+--------------------------+
| i | dto3 | plusZ |
+---+--------------------------+--------------------------+
| 1 | 2017-09-13T01:00:00.003Z | 2017-09-13T01:00:00.003Z |
| 2 | 2017-09-13T02:00:00.333Z | 2017-09-13T02:00:00.333Z |
| 3 | 2017-09-13T03:00:00Z | 2017-09-13T03:00:00Z |
| 4 | 2017-09-13T04:00:00Z | 2017-09-13T04:00:00Z |
| 5 | 2017-09-13T14:12:34.567Z | 2017-09-13T14:12:34.567Z |
+---+--------------------------+--------------------------+
In SQL Server 2012+ the above works as well, though you could use format() if you wanted to always have 0s for milliseconds:
format(timestamp,'yyyy-MM-ddTHH:mm:ss.fffZ')
But format() can be slower, take a look here: format() is nice and all, but… - Aaron Bertrand
You may possible need to use the same code formatting but create a case statement for when milliseconds = 0

Two questions for formatting timestamp and number using postgresql

I am selecting a date column which is in the format "YYYY-MM-DD".
I want to cast it to a timestamp such that it will be "YYYY-MM-DD HH:MM:SS:MS"
I attempted:
select CAST(mycolumn as timestamp) from mytable;
but this resulted in the format YYYY-MM-DD HH:MM:SS
I also tried
select TO_TIMESTAMP(mycolumn,YYYY-MM-DD HH:MM:SS:MS) from mytable;
but this did not work either. I cannot seem to figure out the correct way to format this. Note that I only want the first digit of the milliseconds.
//////////////second question
I am also trying to select numeric data such that there will not be any trailing zeros.
For example, if I have values in a table such as 1, 2.00, 3.34, 4.50.
I want to be able to select those values as 1, 2, 3.34, 4.5.
I tried using ::float, but I occasionally strange output. I also tried the rounding function, but how could I use it properly without knowing how many decimal points I need before hand?
thanks for your help!
It seems that the functions to_timestamp() and to_char() are unfortunately not perfect.
If you cannot find anything better, use these workarounds:
with example_data(d) as (
values ('2016-02-02')
)
select d, d::timestamp || '.0' tstamp
from example_data;
d | tstamp
------------+-----------------------
2016-02-02 | 2016-02-02 00:00:00.0
(1 row)
create function my_to_char(numeric)
returns text language sql as $$
select case
when strpos($1::text, '.') = 0 then $1::text
else rtrim($1::text, '.0')
end
$$;
with example_data(n) as (
values (100), (2.00), (3.34), (4.50))
select n::text, my_to_char(n)
from example_data;
n | my_to_char
------+------------
100 | 100
2.00 | 2
3.34 | 3.34
4.50 | 4.5
(4 rows)
See also: How to remove the dot in to_char if the number is an integer
SELECT to_char(current_timestamp, 'YYYY-MM-DD HH:MI:SS:MS');
prints
2016-02-05 03:21:18:346
just add ::timestamp without time zone
select mycolumn::timestamp without time zone from mytable;