Come posso convertire bigint (timestamp UNIX) in datetime in SQL Server?


Risposte:


58

provare:

CREATE FUNCTION dbo.fn_ConvertToDateTime (@Datetime BIGINT)
RETURNS DATETIME
AS
BEGIN
    DECLARE @LocalTimeOffset BIGINT
           ,@AdjustedLocalDatetime BIGINT;
    SET @LocalTimeOffset = DATEDIFF(second,GETDATE(),GETUTCDATE())
    SET @AdjustedLocalDatetime = @Datetime - @LocalTimeOffset
    RETURN (SELECT DATEADD(second,@AdjustedLocalDatetime, CAST('1970-01-01 00:00:00' AS datetime)))
END;
GO

2
+1 Per la conversione UTC-> locale. Nota che l'ora estiva / invernale sarà ancora disattivata se provi a tradurre il 10 giugno nel mese di febbraio.
Andomar

11
-1 per la conversione UTC-> locale. Non gestisce correttamente l'ora legale. Per me, questo è fuorviante.
Pavel Horal,

+1 per la soluzione creativa! Funziona alla grande. Cordiali saluti, c'è un errore di sintassi nell'SQL. Il punto e virgola alla fine della prima riga "DECLARE" deve essere rimosso poiché segue una virgola.
Seth

2
Non funziona per me. Lo sto provando con 1517270400000 e ricevo questo errore: errore di overflow aritmetico durante la conversione dell'espressione nel tipo di dati int.
Danese

1
Inoltre stava ottenendo un overflow, che normalmente significa che sono coinvolti millisecondi, risolto semplicemente come: select dbo.fn_ConvertToDateTime (src_column / 1000) da src_table;
access_granted

304

Questo ha funzionato per me:

Select
    dateadd(S, [unixtime], '1970-01-01')
From [Table]

Nel caso qualcuno si chieda perché 1970-01-01, questo è chiamato Epoch time .

Di seguito una citazione da Wikipedia:

Il numero di secondi trascorsi dalle 00:00:00 ora UTC (Coordinated Universal Time), giovedì 1 gennaio 1970, [1] [nota 1] senza contare i secondi intercalari.


17
Questo dovrebbe essere contrassegnato come corretto. Vorrei poter votare di nuovo questa risposta ogni volta che
atterro

2
@ BenDundee sono davvero d'accordo con te. Che soluzione elegante. Ho cercato una formula dappertutto e alla fine ho optato per una solo per dover ricominciare a cercare quando ho iniziato a incappare in errori una settimana dopo. Per fortuna ho trovato questo al secondo giro.
sbilenco

1
Sto usando questa soluzione. Questa data formattata era concatenata con altri dati, quindi ho avuto un varchar ... Facile! Non c'è bisogno di preoccuparsi di formattare quei registri nell'applicazione. Tuttavia, sono comparsi alcuni problemi di fuso orario selvaggi! Le mie date utilizzavano il fuso orario UTC invece del fuso orario del cliente :(
gustavohenke

2
@Whitecat Non so se hai già risolto il tuo problema, ma guarda il case! Forse l'impostazione delle regole di confronto del database è impostata su qualcosa come "SQL_Latin1_General_CP1_CS_AS", CS è la parola chiave qui. Sta per "CaseSensitiv" quindi il tuo codice deve corrispondere al case! Un altro punto potrebbe essere che il tuo sistema è MySql, quindi il nome è date_add (). Saluti;)
Nightking

3
Questa soluzione sarà interessata dal problema dell'anno 2038 perché la funzione dateadd richiede un tipo int. La documentazione dice "L'argomento numero non può superare l'intervallo di int." docs.microsoft.com/en-us/sql/t-sql/functions/… en.wikipedia.org/wiki/Year_2038_problem
Patrick H

30

Se qualcuno riceve l'errore di seguito:

Errore di overflow aritmetico durante la conversione dell'espressione nel tipo di dati int

a causa del timestamp unix è in bigint (invece di int), puoi usare questo:

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

Sostituisci il timestamp hardcoded per la colonna effettiva con unix-timestamp

Fonte: MSSQL bigint Unix Timestamp a Datetime con millisecondi


Dati i millisecondi dell'epoca, ancora meglio: SELECT DATEADD (ms, 1517270454852% 1000, DATEADD (S, 1517270454852/1000, '1970-01-01'))
G DeMasters

25

Come questo

aggiungere il datetime Unix (epoch) alla data di base in secondi

questo per ora lo otterrà (2010-05-25 07: 56: 23.000)

 SELECT dateadd(s,1274756183,'19700101 05:00:00:000')

Se vuoi tornare indietro, dai un'occhiata a questo http://wiki.lessthandot.com/index.php/Epoch_Date


1
perché 05:00:00 invece di 00:00:00?
Svisstack

2
@Svisstack le 5 ore sono per la differenza di fuso orario. 5:00:00 significa che è GMT-5 ore
Jordy van Eijk

Funziona come un fascino. Se devi regolare il fuso orario, fallo sicuramente, ma considera questo molto efficiente
clifton_h

7

Questo lo farà:

declare @UNIX_TIME int
select @UNIX_TIME = 1111111111
-- Using dateadd to add seconds to 1970-01-01
select [Datetime from UNIX Time] = dateadd(!precision!,@UNIX_TIME,'1970-01-01')

Invece di! Precisione! utilizzare: ss, ms o mcs a seconda della precisione del timestamp. Bigint è in grado di mantenere una precisione al microsecondo.



4

L'aggiunta di n secondi a 1970-01-01ti darà una data UTC perché n , il timestamp Unix, è il numero di secondi trascorsi dalle 00:00:00 UTC (Coordinated Universal Time), giovedì 1 gennaio 1970 .

In SQL Server 2016 è possibile convertire un fuso orario in un altro utilizzando AT TIME ZONE. Hai solo bisogno di conoscere il nome del fuso orario nel formato standard di Windows:

SELECT *
FROM (VALUES (1514808000), (1527854400)) AS Tests(UnixTimestamp)
CROSS APPLY (SELECT DATEADD(SECOND, UnixTimestamp, '1970-01-01') AT TIME ZONE 'UTC') AS CA1(UTCDate)
CROSS APPLY (SELECT UTCDate AT TIME ZONE 'Pacific Standard Time') AS CA2(LocalDate)
| UnixTimestamp | UTCDate                    | LocalDate                  |
|---------------|----------------------------|----------------------------|
| 1514808000    | 2018-01-01 12:00:00 +00:00 | 2018-01-01 04:00:00 -08:00 |
| 1527854400    | 2018-06-01 12:00:00 +00:00 | 2018-06-01 05:00:00 -07:00 |

O semplicemente:

SELECT *, DATEADD(SECOND, UnixTimestamp, '1970-01-01') AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time'
FROM (VALUES (1514808000), (1527854400)) AS Tests(UnixTimestamp)
| UnixTimestamp | LocalDate                  |
|---------------|----------------------------|
| 1514808000    | 2018-01-01 04:00:00 -08:00 |
| 1527854400    | 2018-06-01 05:00:00 -07:00 |

Appunti:

  • Puoi tagliare le informazioni sul fuso orario trasmettendo DATETIMEOFFSETa DATETIME.
  • La conversione tiene conto dell'ora legale. Il fuso orario del Pacifico era UTC-08:00 a gennaio 2018 e UTC-07: 00 a giugno 2018.

3

Se il tempo è in millisecondi e occorre preservarli:

DECLARE @value VARCHAR(32) = '1561487667713';

SELECT DATEADD(MILLISECOND, CAST(RIGHT(@value, 3) AS INT) - DATEDIFF(MILLISECOND,GETDATE(),GETUTCDATE()), DATEADD(SECOND, CAST(LEFT(@value, 10) AS INT), '1970-01-01T00:00:00'))

1

Questo sta costruendo il lavoro che Daniel Little ha fatto per questa domanda, ma tenendo conto dell'ora legale (funziona per le date 01-01 1902 e successive a causa del limite int sulla funzione dateadd):

Dobbiamo prima creare una tabella che memorizzerà gli intervalli di date per l'ora legale (fonte: History of time in the United States ):

CREATE TABLE [dbo].[CFG_DAY_LIGHT_SAVINGS_TIME](
  [BEGIN_DATE] [datetime] NULL,
  [END_DATE] [datetime] NULL,
  [YEAR_DATE] [smallint] NULL
) ON [PRIMARY]

GO

INSERT INTO CFG_DAY_LIGHT_SAVINGS_TIME VALUES
('2001-04-01 02:00:00.000',   '2001-10-27 01:59:59.997',    2001),
('2002-04-07 02:00:00.000',   '2002-10-26 01:59:59.997',    2002),
('2003-04-06 02:00:00.000',   '2003-10-25 01:59:59.997',    2003),
('2004-04-04 02:00:00.000',   '2004-10-30 01:59:59.997',    2004),
('2005-04-03 02:00:00.000',   '2005-10-29 01:59:59.997',    2005),
('2006-04-02 02:00:00.000',   '2006-10-28 01:59:59.997',    2006),
('2007-03-11 02:00:00.000',   '2007-11-03 01:59:59.997',    2007),
('2008-03-09 02:00:00.000',   '2008-11-01 01:59:59.997',    2008),
('2009-03-08 02:00:00.000',   '2009-10-31 01:59:59.997',    2009),
('2010-03-14 02:00:00.000',   '2010-11-06 01:59:59.997',    2010),
('2011-03-13 02:00:00.000',   '2011-11-05 01:59:59.997',    2011),
('2012-03-11 02:00:00.000',   '2012-11-03 01:59:59.997',    2012),
('2013-03-10 02:00:00.000',   '2013-11-02 01:59:59.997',    2013),
('2014-03-09 02:00:00.000',   '2014-11-01 01:59:59.997',    2014),
('2015-03-08 02:00:00.000',   '2015-10-31 01:59:59.997',    2015),
('2016-03-13 02:00:00.000',   '2016-11-05 01:59:59.997',    2016),
('2017-03-12 02:00:00.000',   '2017-11-04 01:59:59.997',    2017),
('2018-03-11 02:00:00.000',   '2018-11-03 01:59:59.997',    2018),
('2019-03-10 02:00:00.000',   '2019-11-02 01:59:59.997',    2019),
('2020-03-08 02:00:00.000',   '2020-10-31 01:59:59.997',    2020),
('2021-03-14 02:00:00.000',   '2021-11-06 01:59:59.997',    2021),
('2022-03-13 02:00:00.000',   '2022-11-05 01:59:59.997',    2022),
('2023-03-12 02:00:00.000',   '2023-11-04 01:59:59.997',    2023),
('2024-03-10 02:00:00.000',   '2024-11-02 01:59:59.997',    2024),
('2025-03-09 02:00:00.000',   '2025-11-01 01:59:59.997',    2025),
('1967-04-30 02:00:00.000',   '1967-10-29 01:59:59.997',    1967),
('1968-04-28 02:00:00.000',   '1968-10-27 01:59:59.997',    1968),
('1969-04-27 02:00:00.000',   '1969-10-26 01:59:59.997',    1969),
('1970-04-26 02:00:00.000',   '1970-10-25 01:59:59.997',    1970),
('1971-04-25 02:00:00.000',   '1971-10-31 01:59:59.997',    1971),
('1972-04-30 02:00:00.000',   '1972-10-29 01:59:59.997',    1972),
('1973-04-29 02:00:00.000',   '1973-10-28 01:59:59.997',    1973),
('1974-01-06 02:00:00.000',   '1974-10-27 01:59:59.997',    1974),
('1975-02-23 02:00:00.000',   '1975-10-26 01:59:59.997',    1975),
('1976-04-25 02:00:00.000',   '1976-10-31 01:59:59.997',    1976),
('1977-04-24 02:00:00.000',   '1977-10-31 01:59:59.997',    1977),
('1978-04-30 02:00:00.000',   '1978-10-29 01:59:59.997',    1978),
('1979-04-29 02:00:00.000',   '1979-10-28 01:59:59.997',    1979),
('1980-04-27 02:00:00.000',   '1980-10-26 01:59:59.997',    1980),
('1981-04-26 02:00:00.000',   '1981-10-25 01:59:59.997',    1981),
('1982-04-25 02:00:00.000',   '1982-10-25 01:59:59.997',    1982),
('1983-04-24 02:00:00.000',   '1983-10-30 01:59:59.997',    1983),
('1984-04-29 02:00:00.000',   '1984-10-28 01:59:59.997',    1984),
('1985-04-28 02:00:00.000',   '1985-10-27 01:59:59.997',    1985),
('1986-04-27 02:00:00.000',   '1986-10-26 01:59:59.997',    1986),
('1987-04-05 02:00:00.000',   '1987-10-25 01:59:59.997',    1987),
('1988-04-03 02:00:00.000',   '1988-10-30 01:59:59.997',    1988),
('1989-04-02 02:00:00.000',   '1989-10-29 01:59:59.997',    1989),
('1990-04-01 02:00:00.000',   '1990-10-28 01:59:59.997',    1990),
('1991-04-07 02:00:00.000',   '1991-10-27 01:59:59.997',    1991),
('1992-04-05 02:00:00.000',   '1992-10-25 01:59:59.997',    1992),
('1993-04-04 02:00:00.000',   '1993-10-31 01:59:59.997',    1993),
('1994-04-03 02:00:00.000',   '1994-10-30 01:59:59.997',    1994),
('1995-04-02 02:00:00.000',   '1995-10-29 01:59:59.997',    1995),
('1996-04-07 02:00:00.000',   '1996-10-27 01:59:59.997',    1996),
('1997-04-06 02:00:00.000',   '1997-10-26 01:59:59.997',    1997),
('1998-04-05 02:00:00.000',   '1998-10-25 01:59:59.997',    1998),
('1999-04-04 02:00:00.000',   '1999-10-31 01:59:59.997',    1999),
('2000-04-02 02:00:00.000',   '2000-10-29 01:59:59.997',    2000)
GO

Ora creiamo una funzione per ogni fuso orario americano. Questo presuppone che il tempo unix sia in millisecondi. Se è in secondi, rimuovere / 1000 dal codice:

Pacifico

create function [dbo].[UnixTimeToPacific] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @pacificdatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @pacificdatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -7 else -8 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @pacificdatetime is null 
       select @pacificdatetime= dateadd(hour, -7, @interimdatetime)
return @pacificdatetime    
end

Orientale

create function [dbo].[UnixTimeToEastern] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @easterndatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @easterndatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -4 else -5 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @easterndatetime is null 
       select @easterndatetime= dateadd(hour, -4, @interimdatetime)
return @easterndatetime    
end

Centrale

create function [dbo].[UnixTimeToCentral] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @centraldatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @centraldatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -5 else -6 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @centraldatetime is null 
       select @centraldatetime= dateadd(hour, -5, @interimdatetime)
return @centraldatetime    
end

Montagna

create function [dbo].[UnixTimeToMountain] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @mountaindatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @mountaindatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -6 else -7 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @mountaindatetime is null 
       select @mountaindatetime= dateadd(hour, -6, @interimdatetime)
return @mountaindatetime    
end

Hawaii

create function [dbo].[UnixTimeToHawaii] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @hawaiidatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @hawaiidatetime =  dateadd(hour,-10,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)

return @hawaiidatetime    
end

Arizona

create function [dbo].[UnixTimeToArizona] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @arizonadatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @arizonadatetime =  dateadd(hour,-7,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)

return @arizonadatetime    
end

Alaska

create function [dbo].[UnixTimeToAlaska] 
 (@unixtime bigint)
   returns datetime
   as
   begin
     declare @alaskadatetime datetime
     declare @interimdatetime datetime = dateadd(s, @unixtime/1000, '1970-01-01')
     select  @alaskadatetime =  dateadd(hour,case when @interimdatetime between begin_date and end_date then -8 else -9 end  ,@interimdatetime)
     from cfg_day_light_savings_time  where  year_date = datepart(year,@interimdatetime)
     if @alaskadatetime is null 
       select @alaskadatetime= dateadd(hour, -8, @interimdatetime)
return @alaskadatetime    
end

1
//BIGINT UNIX TIMESTAMP CONVERSION upto Millisecond Accuracy
CREATE FUNCTION [dbo].[ConvertUnixTimestamp] (@Datetime [BIGINT]) RETURNS DATETIME
AS
BEGIN

    RETURN DATEADD(MILLISECOND, cast(@Datetime as bigint) % 1000, 
    DATEADD(SECOND, (cast(@Datetime as bigint) / 1000)%60, 
    DATEADD(MINUTE, ((cast(@Datetime as bigint) / 1000)/60)%60, 
    DATEADD(HOUR, ((cast(@Datetime as bigint) / 1000)/60)/60, '19700101'))))
END

1

Anch'io ho dovuto affrontare questo problema. Sfortunatamente, nessuna delle risposte (qui e in dozzine di altre pagine) è stata soddisfacente per me, poiché non riesco ancora a raggiungere date oltre l'anno 2038 a causa di cast di interi a 32 bit da qualche parte.

Una soluzione che ha funzionato per me alla fine è stata quella di utilizzare le floatvariabili, in modo da poter avere almeno una data massima di 2262-04-11T23:47:16.854775849. Tuttavia, questo non copre l'intero datetimedominio, ma è sufficiente per le mie esigenze e può aiutare altri che incontrano lo stesso problema.

-- date variables
declare @ts bigint; -- 64 bit time stamp, 100ns precision
declare @d datetime2(7) = GETUTCDATE(); -- 'now'
-- select @d = '2262-04-11T23:47:16.854775849'; -- this would be the max date

-- constants:
declare @epoch datetime2(7) = cast('1970-01-01T00:00:00' as datetime2(7));
declare @epochdiff int = 25567; -- = days between 1900-01-01 and 1970-01-01
declare @ticksofday bigint = 864000000000; -- = (24*60*60*1000*1000*10)

-- helper variables:
declare @datepart float;
declare @timepart float;
declare @restored datetime2(7);

-- algorithm:
select @ts = DATEDIFF_BIG(NANOSECOND, @epoch, @d) / 100; -- 'now' in ticks according to unix epoch
select @timepart = (@ts % @ticksofday) / @ticksofday; -- extract time part and scale it to fractional part (i. e. 1 hour is 1/24th of a day)
select @datepart = (@ts - @timepart) / @ticksofday; -- extract date part and scale it to fractional part
select @restored = cast(@epochdiff + @datepart + @timepart as datetime); -- rebuild parts to a datetime value

-- query original datetime, intermediate timestamp and restored datetime for comparison
select
  @d original,
  @ts unix64,
  @restored restored
;

-- example result for max date:
-- +-----------------------------+-------------------+-----------------------------+
-- | original                    | unix64            | restored                    |
-- +-----------------------------+-------------------+-----------------------------+
-- | 2262-04-11 23:47:16.8547758 | 92233720368547758 | 2262-04-11 23:47:16.8533333 |
-- +-----------------------------+-------------------+-----------------------------+

Ci sono alcuni punti da considerare:

  • La precisione di 100ns è il requisito nel mio caso, tuttavia questa sembra essere la risoluzione standard per i timestamp unix a 64 bit. Se usi qualsiasi altra risoluzione, devi regolare di conseguenza @ticksofdayla prima riga dell'algoritmo.
  • Sto usando altri sistemi che hanno i loro problemi con i fusi orari, ecc. E ho scoperto che la soluzione migliore per me sarebbe sempre usare UTC. Per le tue esigenze, questo potrebbe differire.
  • 1900-01-01è la data di origine di datetime2, proprio come l'epoca 1970-01-01per i timestamp unix.
  • floats mi ha aiutato a risolvere il problema dell'anno 2038 e gli overflow di interi e simili, ma tieni presente che i numeri in virgola mobile non sono molto performanti e possono rallentare l'elaborazione di una grande quantità di timestamp. Inoltre, i float possono portare alla perdita di precisione a causa di errori di arrotondamento, come puoi vedere nel confronto dei risultati di esempio per la data massima sopra (qui, l'errore è di circa 1,4425 ms).
  • Nell'ultima riga dell'algoritmo c'è un cast a datetime. Sfortunatamente, non esiste un cast esplicito da valori numerici a datetime2consentito, ma è consentito eseguire il cast datetimeesplicito di valori numerici a e questo, a sua volta, viene cast implicitamente a datetime2. Questo potrebbe essere corretto, per ora, ma potrebbe cambiare nelle versioni future di SQL Server: o ci sarà una dateadd_big()funzione o datetime2sarà consentito il cast esplicito o il cast esplicito datetimenon sarà consentito, quindi questo potrebbe interrompersi o potrebbe verificarsi un modo più semplice un giorno.

1

Per GMT, ecco il modo più semplice:

Select dateadd(s, @UnixTime+DATEDIFF (S, GETUTCDATE(), GETDATE()), '1970-01-01')

0

Meglio? Questa funzione converte unixtime in millisecondi in datetime. Ha perso millisecondi, ma è comunque molto utile per il filtraggio.

CREATE FUNCTION [dbo].[UnixTimestampToGMTDatetime] 
(@UnixTimestamp bigint)
RETURNS datetime
AS
BEGIN
       DECLARE @GMTDatetime datetime
       select @GMTDatetime = 
       CASE
       WHEN dateadd(ss, @UnixTimestamp/1000, '1970-01-01') 
       BETWEEN 
           Convert(DATETIME, Convert(VARCHAR(4), Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )) + '-03-' + Convert(VARCHAR(2), (31 - (5 * Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )/4 + 4) % 7)) + ' 01:00:00', 20)
       AND
           Convert(DATETIME, Convert(VARCHAR(4), Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )) + '-10-' + Convert(VARCHAR(2), (31 - (5 * Year(dateadd(ss, @UnixTimestamp/1000, '1970-01-01') )/4 + 1) % 7)) + ' 02:00:00', 20)
       THEN Dateadd(hh, 1, dateadd(ss, @UnixTimestamp/1000, '1970-01-01'))
       ELSE Dateadd(hh, 0, dateadd(ss, @UnixTimestamp/1000, '1970-01-01'))
       END
RETURN @GMTDatetime    
END

0

La soluzione può essere la seguente:

DECLARE @UnixTimeStamp bigint = 1564646400000 /*2019-08-01 11:00 AM*/

DECLARE @LocalTimeOffset bigint = DATEDIFF(MILLISECOND, GETDATE(), GETUTCDATE());
DECLARE @AdjustedTimeStamp bigint = @UnixTimeStamp - @LocalTimeOffset;
SELECT [DateTime] = DATEADD(SECOND, @AdjustedTimeStamp % 1000, DATEADD(SECOND, @AdjustedTimeStamp / 1000, '19700101'));

0

@DanielLittle ha la risposta più semplice ed elegante alla domanda specifica. Tuttavia, se sei interessato alla conversione in un fuso orario specifico E tenendo conto dell'ora legale (DST), quanto segue funziona bene:

CAST(DATEADD(S, [UnixTimestamp], '1970-01-01') AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS Datetime)

Nota: questa soluzione funziona solo su SQL Server 2016 e versioni successive (e Azure).

Per creare una funzione:

CREATE FUNCTION dbo.ConvertUnixTime (@input INT)
RETURNS Datetime
AS BEGIN
    DECLARE @Unix Datetime

    SET @Unix = CAST(DATEADD(S, @Input, '1970-01-01') AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS Datetime)

    RETURN @Unix
END

Puoi chiamare la funzione in questo modo:

SELECT   dbo.ConvertUnixTime([UnixTimestamp])
FROM     YourTable
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.