Home > Software design >  What is the best way to convert a long datetime into an actual datetime in a SQL Server database?
What is the best way to convert a long datetime into an actual datetime in a SQL Server database?

Time:10-28

In my Microsoft SQL Server database, every date or datetime is represented as a decimal(17,0) value.

For example: 20210722054500000 would translate to 2021-07-22 05:45:00:000

I already came up with an solution to convert this:

SELECT 
    CONVERT(datetime, (SUBSTRING(CAST(20210722054500000 AS varchar(20)), 1, 4)   '-'   
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 5, 2)   '-'   
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 7, 2)   ' '   
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 9, 2)   ':'   
                       SUBSTRING(CAST(20210722054500000 AS varchar(20)), 11, 2)   ':00'), 120)

It works, but I feel there should be an better solution to convert this.

So my question is has anybody an approach that requires less code or would be better in regards to performance?

CodePudding user response:

One way is to extract the parts using a simple set of substrings. Given this table and data:

CREATE TABLE dbo.WhoDesignedThis
(
  Id int,
  TheDate decimal(17,0) -- this was hard to write with a straight face
);

INSERT dbo.WhoDesignedThis(Id, TheDate) VALUES
(1, 20210722054500000),
(2, 19991231132247699);

This query:

;WITH x AS
(
  SELECT Id, TheDate, x = CONVERT(char(17), TheDate) 
  FROM dbo.WhoDesignedThis
)
SELECT Id, TheDate, output = DATETIMEFROMPARTS
  (
    LEFT(x,4), 
    SUBSTRING(x,5,2), 
    SUBSTRING(x,7,2), 
    SUBSTRING(x,9,2), 
    SUBSTRING(x,11,2), 
    SUBSTRING(x,13,2), 
    RIGHT(x,3)
  )
FROM x;

Produces these results:

Id TheDate output
1 20210722054500000 2021-07-22 05:45:00.000
2 19991231132247699 1999-12-31 13:22:47.700

CodePudding user response:

You can do it without casts and string functions, using datetimefromparts:

declare @input decimal(17,0) = 20210722054500000
select DATETIMEFROMPARTS(
    @input/10000000000000      ,-- year
    @input/100000000000 % 100  ,-- month
    @input/1000000000 % 100    ,-- day
    @input/10000000 % 100      ,-- hour
    @input/100000%100          ,-- minute
    @input/1000%100            ,-- seconds
    @input%1000                -- milliseconds 
)
  • Related