Você deve ter notado que o SQL Server não possui um equivalente do
UNIX_TIMESTAMP()
do MySQL função. No entanto, não é tão difícil retornar o timestamp Unix no SQL Server.
O timestamp Unix (também conhecido como Unix Epoch time, Unix time ou POSIX time) é simplesmente o número de segundos decorridos desde 00:00:00 de quinta-feira, 1 de janeiro de 1970, Coordinated Universal Time (UTC). Portanto, no SQL Server, podemos usar algumas funções T-SQL para retornar isso.
Carimbo de data/hora Unix do SQL Server
Veja como você pode retornar o carimbo de data/hora do Unix no SQL Server.
SELECT DATEDIFF(SECOND,'1970-01-01', GETUTCDATE()) AS 'SQL Server Result';
Resultado:
+---------------------+ | SQL Server Result | |---------------------| | 1560833178 | +---------------------+
Então podemos usar o
DATEDIFF()
função para retornar a diferença em segundos entre 1970-01-01 e agora. Usamos o GETUTCDATE()
função para retornar a data e hora atuais na hora UTC. Este código funcionará até o ano de 2038 ('2038-01-19 03:14:07' para ser mais preciso). Para timestamps Unix depois disso, você precisará modificar o código um pouco. Se você precisar de um carimbo de data/hora Unix após essa data, continue lendo.
Equivalente de carimbo de data/hora do MySQL Unix
Para uma comparação, se eu executar o
UNIX_TIMESTAMP()
do MySQL exatamente ao mesmo tempo, recebo isso:SELECT UNIX_TIMESTAMP() AS 'MySQL Result';
Resultado:
+--------------+ | MySQL Result | +--------------+ | 1560833178 | +--------------+
Mesmo resultado. O MySQL retorna o resultado como um inteiro sem sinal. No entanto, se o argumento de data (opcional) for passado, ele suporta o mesmo intervalo que o
TIMESTAMP
tipo de dados. Retorne os milissegundos
Se você precisar retornar um timestamp Unix com maior precisão, digamos, o número de milissegundos desde '1970-01-01 00:00:00.000' UTC, você precisará trocar o
DATEDIFF()
função para DATEDIFF_BIG()
. Isso ocorre porque
DATEDIFF()
retorna um int , que é muito pequeno para lidar com o número de milissegundos desde 1970. O DATEDIFF_BIG()
por outro lado, retorna um bigint assinado , que é mais do que suficiente para lidar com milissegundos. SELECT DATEDIFF_BIG(MILLISECOND,'1970-01-01 00:00:00.000', SYSUTCDATETIME()) Milliseconds;
Resultado:
+----------------+ | Milliseconds | |----------------| | 1560835305461 | +----------------+
Retorne os Nanossegundos
Aqui está outro exemplo, desta vez indo até os nanossegundos desde '1970-01-01 00:00:00.0000000' UTC.
SELECT DATEDIFF_BIG(NANOSECOND,'1970-01-01 00:00:00.0000000', SYSUTCDATETIME()) Nanoseconds;
Resultado:
+---------------------+ | Nanoseconds | |---------------------| | 1560835321500279300 | +---------------------+
O problema do ano de 2038
Retornar milissegundos, microssegundos e nanossegundos é muito bom, mas estritamente falando, não é o verdadeiro tempo Unix Epoch. O tempo Unix Epoch é o número de segundos desde '1970-01-01 00:00:00'.
No entanto, o
DATEDIFF_BIG()
ainda pode ser útil ao retornar o tempo estrito do Unix Epoch. Em particular, isso pode ajudar seu banco de dados a superar o problema de 2038. Nesse caso, qualquer coisa após '2038-01-19 03:14:07' precisará ser retornada como bigint (um inteiro de 8 bytes). Isso ocorre porque o número de segundos será muito grande para um int tipo de dados (um inteiro de 4 bytes). O int tipo de dados só vai até 2.147.483.647, enquanto um bigint sobe para 9.223.372.036.854.775.807. Portanto, para retornar carimbos de data/hora Unix após '2038-01-19 03:14:07', use o
DATEDIFF_BIG()
função em vez de DATEDIFF()
. Para demonstrar isso, aqui está um exemplo de uso de
DATEDIFF()
para retornar a hora Unix exatamente nessa data/hora:SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:07') AS 'Unix Epoch time';
Resultado:
+-------------------+ | Unix Epoch time | |-------------------| | 2147483647 | +-------------------+
Até agora tudo bem. Este resultado está dentro do int intervalo de -2.147.483.648 a 2.147.483.647 (embora esteja bem no limite superior) para que o resultado correto seja retornado.
Mas aqui está o que acontece se aumentarmos em um segundo:
SELECT DATEDIFF(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';
Resultado:
The datediff function resulted in an overflow. The number of dateparts separating two date/time instances is too large. Try to use datediff with a less precise datepart.
Recebemos o erro porque o valor retornado estaria fora do int alcance.
Então, como mencionado, tudo o que precisamos fazer é trocar
DATEDIFF()
para DATEDIFF_BIG()
:SELECT DATEDIFF_BIG(SECOND,'1970-01-01', '2038-01-19 03:14:08') AS 'Unix Epoch time';
Resultado:
+-------------------+ | Unix Epoch time | |-------------------| | 2147483648 | +-------------------+
No entanto, isso não resolverá necessariamente todos os problemas do ano de 2038, pois a maioria dos problemas em potencial provavelmente seria derivada do sistema operacional.
Também devo salientar que nenhum desses códigos não será necessariamente imune ao “Problema do Ano 10.000”, porque envolve o datetime2 tipo de dados, que tem um intervalo superior de '9999-12-31'.