Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MSSQL bigint Unix Timestamp to Datetime with milliseconds

I have some timestamps that are in bigint. Here's one:

1462924862735870900

This is down to microsecond precision.

I am currently using this:

SELECT DATEADD(S, CONVERT(int,LEFT(1462924862735870900, 10)), '1970-01-01')

That's giving me datetime down to the second but I would like to maintain at least millisecond precision.

I realize that DATEADD cannot handle bigint that's why I truncated the bigint and converted it to int. If I don't do that I get this error:

Arithmetic overflow error converting expression to data type int

I'm hoping someone can help me figure out a better way to convert this and maintain at least millisecond precision.

Any help would be greatly appreciated. Thanks!

---- UPDATE ------

With the help of @ako, I threw together a function that takes a bigint timestamp in either milliseconds, microseconds or nanoseconds and returns DATETIME2(7) which is 100 nanosecond precision. It could probably be more efficient but here's the function:

CREATE FUNCTION [dbo].[fn_tsConvert] (@ts bigint)
RETURNS DATETIME2(7)
AS BEGIN
    DECLARE @ts2 DATETIME2(7)

    -- MILLISECOND
    IF(LEN(@ts) = 13)
        SET @ts2 = DATEADD(HH,-4,DATEADD(MILLISECOND, @ts % 1000, DATEADD(SECOND, @ts / 1000, CAST('1970-01-01' as datetime2(7)))))

    -- MICROSECOND  
    IF(LEN(@ts) = 16)
        SET @ts2 = DATEADD(HH,-4,DATEADD(MICROSECOND, @ts % 1000000, DATEADD(SECOND, @ts / 1000000, CAST('1970-01-01' as datetime2(7)))))

    -- NANOSECOND   
    IF(LEN(@ts) = 19)
        SET @ts2 = DATEADD(HH,-4,DATEADD(NANOSECOND, @ts % 1000000000, DATEADD(SECOND, @ts / 1000000000, CAST('1970-01-01' as datetime2(7)))))

    RETURN @ts2

END
like image 588
Sequenzia Avatar asked May 11 '16 01:05

Sequenzia


People also ask

How to get the milliseconds out of the Unix timestamp?

To get the milliseconds out of the unix timestamp and into the datetime column. But your epoch timestamp has no millisecond part in the first place. I'm using Math.round ( (new Date ()).getTime () / 1000); to get the unix timestamp from JS.

How to use $SQL to get the timestamp of a table?

$sql = " INSERT INTO assoc_table (timestart, timeend) VALUES (TO_TIMESTAMP (:timestart), TO_TIMESTAMP (:timeend)) "; For some reason it does not register the milliseconds.

How do I convert Unix to UTC in SQL Server 2016?

Adding n seconds to 1970-01-01 will give you a UTC date because n, the Unix timestamp, is the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970. In SQL Server 2016, you can convert one time zone to another using AT TIME ZONE.

Why is the date broken down into minutes and milliseconds?

The breakdown in minutes and milliseconds (ms) is to prevent that the value overflows the maximum value of int (which would throw a runtime error for the function DateAdd ()) What is that bigint supposed to mean? Would you have the timestamp for a known date (like today)? Hi hussain try this...


1 Answers

I think that you are dealing with nanosecond precision. What you can get in native sql is 100ns precision.

declare @ts as bigint = 1462924862735870900

select dateadd(NANOSECOND, @ts % 1000000000, dateadd(SECOND, @ts / 1000000000, cast('1970-01-01' as datetime2(7))))

The outcome is 2016-05-11 00:01:02.7358709

like image 199
Ako Avatar answered Sep 21 '22 23:09

Ako