Como posso converter bigint (carimbo de data / hora UNIX) em data e hora no SQL Server?

Respostas:

57

experimentar:

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
KM.
fonte
2
+1 Para a conversão UTC-> local. Observe que o verão / inverno ainda estará fora se você tentar traduzir 10 de junho durante fevereiro.
Andomar
11
-1 para a conversão UTC-> local. Ele não está tratando corretamente o horário de verão. Para mim, isso é um equívoco.
Pavel Horal
1 para a solução criativa! Funciona bem. FYI, há um erro de sintaxe no SQL. O ponto e vírgula no final da primeira linha "DECLARE" precisa ser removido, pois uma vírgula vem a seguir.
Seth
2
Não funciona para mim. Estou tentando com 1517270400000 e recebendo este erro: Erro de estouro aritmético ao converter a expressão para o tipo de dados int.
Dinamarquês
1
Também estava obtendo um estouro, normalmente significando que milissegundos estão envolvidos, resolvido simplesmente como: select dbo.fn_ConvertToDateTime (src_column / 1000) de src_table;
access_granted
304

Isso funcionou para mim:

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

Caso alguém se pergunte por que 01/01/1970, isso é chamado de época .

Abaixo está uma citação da Wikipedia:

O número de segundos decorridos desde 00:00:00 Coordinated Universal Time (UTC), quinta-feira, 1 de janeiro de 1970, [1] [nota 1] sem contar os segundos bissextos.

Daniel Little
fonte
17
Isso deve ser marcado como correto. Eu gostaria de poder
votar a favor
2
@BenDundee Eu realmente concordo com você. Que solução elegante. Procurei por uma fórmula em todo lugar e finalmente decidi por uma só para ter que procurar novamente quando comecei a ter erros uma semana depois. Felizmente encontrei este na segunda tentativa.
Desequilibrado em
1
Tenho usado essa solução. Esta data formatada foi concatenada com outros dados, então eu tinha um varchar ... Fácil! Não há necessidade de se preocupar em formatar esses logs no aplicativo. No entanto, surgiram alguns problemas de fuso horário! Minhas datas usavam o fuso horário UTC em vez do fuso horário do cliente :(
gustavohenke
2
@Whitecat Não sei se você já resolveu seu problema, mas cuidado com o case! Talvez sua configuração de agrupamento de banco de dados esteja definida como 'SQL_Latin1_General_CP1_CS_AS', CS é a palavra-chave aqui. Significa "CaseSensitiv", portanto, seu código deve corresponder à caixa! Outro ponto pode ser que seu sistema é MySql, então o nome é date_add (). Atenciosamente;)
Nightking de
3
Esta solução será afetada pelo problema do ano 2038 porque a função dateadd requer um tipo int. A documentação diz "O argumento do número não pode exceder o intervalo de int." docs.microsoft.com/en-us/sql/t-sql/functions/… en.wikipedia.org/wiki/Year_2038_problem
Patrick H
30

Se alguém obtiver o erro abaixo:

Erro de estouro aritmético ao converter a expressão para o tipo de dados int

devido ao timestamp unix estar em bigint (em vez de int), você pode usar isto:

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

Substitua o carimbo de data / hora codificado para sua coluna real por carimbo de data / hora unix

Fonte: MSSQL bigint Unix Timestamp para Datetime com milissegundos

jmojico
fonte
Dados milissegundos de época, ainda melhor: SELECT DATEADD (ms, 1517270454852% 1000, DATEADD (S, 1517270454852/1000, '1970-01-01'))
G DeMasters
25

Como isso

adicione a data e hora Unix (época) à data base em segundos

isso vai conseguir por agora (2010-05-25 07: 56: 23.000)

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

Se você quiser voltar, dê uma olhada neste http://wiki.lessthandot.com/index.php/Epoch_Date

SQLMenace
fonte
1
por que 05:00:00 em vez de 00:00:00?
Svisstack
2
@Svisstack as 5 horas são para diferença de fuso horário. 5:00:00 significa GMT-5 horas
Jordy van Eijk
Funciona como um encanto. Se você precisar ajustar para o fuso horário, então certamente faça isso, mas considere isso muito eficiente
clifton_h
7

Isso vai resolver:

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')

Em vez de! Precisão! use: ss, ms ou mcs de acordo com a precisão do timestamp. Bigint é capaz de manter a precisão de microssegundos.

Ovidiu Pacurar
fonte
4

Adicionar n segundos a 1970-01-01fornecerá uma data UTC porque n , o carimbo de data / hora Unix, é o número de segundos decorridos desde 00:00:00 Hora Universal Coordenada (UTC), quinta-feira, 1 de janeiro de 1970 .

No SQL Server 2016, você pode converter um fuso horário em outro usando AT TIME ZONE. Você só precisa saber o nome do fuso horário no formato padrão do 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 |

Ou simplesmente:

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 |

Notas:

  • Você pode cortar as informações de fuso horário lançando DATETIMEOFFSETpara DATETIME.
  • A conversão leva em consideração o horário de verão. O horário do Pacífico era UTC-08: 00 em janeiro de 2018 e UTC-07: 00 em junho de 2018.
Salman A
fonte
3

Se o tempo estiver em milissegundos e for necessário preservá-los:

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'))
gotqn
fonte
1

Este é um desenvolvimento do trabalho que Daniel Little fez para esta questão, mas levando em consideração o horário de verão (funciona para datas 01-01 1902 e superiores devido ao limite interno na função de adição de dados):

Primeiro, precisamos criar uma tabela que armazenará os intervalos de datas para o horário de verão (fonte: Histórico do tempo nos Estados Unidos ):

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

Agora criamos uma função para cada fuso horário americano. Isso supõe que o tempo unix está em milissegundos. Se estiver em segundos, remova / 1000 do código:

Pacífico

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

Oriental

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

Central

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

Montanha

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

Havaí

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

Alasca

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
Jymbo
fonte
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
user3450075
fonte
1

Eu tive que enfrentar esse problema também. Infelizmente, nenhuma das respostas (aqui e em dezenas de outras páginas) foi satisfatória para mim, já que ainda não consigo chegar a datas além do ano 2038 devido a conversões de inteiros de 32 bits em algum lugar.

Uma solução que funcionou para mim no final foi usar floatvariáveis, para que eu pudesse ter pelo menos uma data máxima de 2262-04-11T23:47:16.854775849. Ainda assim, isso não cobre todo o datetimedomínio, mas é suficiente para minhas necessidades e pode ajudar outras pessoas que tenham o mesmo 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 |
-- +-----------------------------+-------------------+-----------------------------+

Existem alguns pontos a serem considerados:

  • Precisão de 100ns é o requisito no meu caso, no entanto, esta parece ser a resolução padrão para carimbos de data / hora unix de 64 bits. Se você usar qualquer outra resolução, terá que ajustar @ticksofdaya primeira linha do algoritmo de acordo.
  • Estou usando outros sistemas que têm problemas de fuso horário etc. e descobri que a melhor solução para mim seria sempre usar o UTC. Para suas necessidades, isso pode ser diferente.
  • 1900-01-01é a data de origem de datetime2, assim como é a época 1970-01-01para carimbos de data / hora unix.
  • floats me ajudaram a resolver o problema do ano 2038 e estouros de inteiros e outros, mas tenha em mente que os números de ponto flutuante não têm muito desempenho e podem retardar o processamento de uma grande quantidade de carimbos de data / hora. Além disso, flutuações podem levar à perda de precisão devido a erros de arredondamento, como você pode ver na comparação dos resultados de exemplo para a data máxima acima (aqui, o erro é de cerca de 1,4425 ms).
  • Na última linha do algoritmo, há uma conversão para datetime. Infelizmente, não há conversão explícita de valores numéricos em datetime2permitidos, mas é permitido converter numéricos para datetimeexplicitamente e isso, por sua vez, é convertido implicitamente para datetime2. Isso pode estar correto, por enquanto, mas pode mudar em versões futuras do SQL Server: Haverá uma dateadd_big()função ou a conversão explícita de datetime2será permitida ou a conversão explícita de datetimeserá proibida, então isso pode falhar ou pode ocorrer uma maneira mais fácil algum dia.
Chris Tophski
fonte
1

Para GMT, esta é a maneira mais fácil:

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

Melhor? Esta função converte unixtime em milissegundos em datetime. Perdeu milissegundos, mas ainda é muito útil para filtrar.

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
MtAt
fonte
0

A solução pode ser a seguinte:

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'));
Vitaly Ilyuhin
fonte
0

@DanielLittle tem a resposta mais fácil e elegante para a pergunta específica. No entanto, se você estiver interessado em converter para um fuso horário específico E levando em consideração o DST (horário de verão), o seguinte funciona bem:

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

Observação: esta solução só funciona no SQL Server 2016 e superior (e no Azure).

Para criar uma função:

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

Você pode chamar a função assim:

SELECT   dbo.ConvertUnixTime([UnixTimestamp])
FROM     YourTable
Kenny
fonte