Esses números possuem vários nomes: Unix timestamps, Unix Time, ou simplesmente timestamps (que é o nome que usaremos a partir de agora). Um timestamp basicamente representa um instante único, um ponto específico na linha do tempo, e seu valor corresponde a uma determinada quantidade de tempo decorrida a partir de um instante inicial.
Por exemplo: digamos que eu deseje armazenar a informação de timestamp atual. Eu teria um dado com a informação de “22/01/2023 12h42m59.456”. Isso dá uma ideia pra você de quando eu estou escrevendo este post. Contudo, essa medida de tempo é relativa ao lugar onde eu estou.
Por isso, só faz sentido converter um timestamp para uma data e hora (e vice-versa) se você estiver usando um fuso-horário específico. Muitas linguagens possuem funções que fazem essas conversões sem pedir por um fuso-horário, mas no fundo elas usam algum predefinido (geralmente o default que está configurado no ambiente em que o código roda). Algumas permitem que você mude ou configure o fuso-horário, mas nem sempre isso é possível.
Há um formato ISO 8601 de representação de datas (na verdade um conjunto de formatos). Isso não tem a ver com o timestamp do unix, é apenas uma forma universal de representar datas, vez que diferentes países a representam de forma diferente, o que pode gerar confusão. Por exemplo, no Brasil costuma-se usar DD/MM/YYYY
, enquanto que nos EUA usa-se MM/DD/YYYY
, na Armênia usa-se DD.MM.YYYY
, no Japão usa-se YYYY年MM月DD日
. (fonte)
No SQL Server, o tipo TIMESTAMP
é uma equivalência deprecated para o tipo ROWVERSION
, que na verdade constitui-se de um campo que é alterado automaticamente sempre que um registro é alterado e armazena um valor garantidamente único, não tendo relação com datas. No SQL Server, o tipo DATETIME
utiliza 8 bytes para armazenar datas de 01/01/1753 até 31/12/9999, com precisão de cerca de 3 milisegundos. Também há o tipo SMALLDATETIME
que utiliza 4 bytes para armazenar datas de 01/01/1900 até 06/06/2079 com precisão de 1 minuto, o tipo DATETIME2
, que armazena qualquer data e hora representável com um ano de quatro dígitos com uma precisão de décimos de milionésimos de segundo. e um tipo DATETIMEOFFSET
que armazena também o fuso horário.
Some 4 dias e obtenha o resto da divisão por 7. Para valores negativos de números de dias (após somar 4), aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 7 ao resto obtido a fim de torná-lo positivo.
Também no MySQL, o TIMESTAMP
sofre do bug do ano 2038, como bem observou o Victor Stafusa; o DATETIME
só vai dar problema no ano 10000.
Web users can easily convert a Unix epoch timestamp to a human-readable date and vice versa using a free online conversion tool. For example, if the Unix epoch time is 1639172876 seconds, then the human date would be Friday, Dec. 10, 2021, at 9:47:56 p.m. This timestamp written in a dd mm yyyy hh mm ss format would be 10-12-2021 9:47:56.
In IP telephony, for example, Real-time Transport Protocol assigns sequential timestamps to voice packets so that they can be buffered by the receiver, reassembled and delivered without error. When writing a program, the programmer is usually provided an application programming interface for a timestamp that the operating system (OS) can provide during program execution.
Fazer a conversão de UTC para Local pode ser perigoso. Ainda que guardar o offset possa ser a primeira solução, ela infelizmente não acrescenta informações de contexto importantes, como as regras para o horário de verão. Ainda tomando a nossa data de exemplo, se eu quiser voltar no tempo com ela para 2019, eu posso ter uma conversão equivocada, já que em 2019 o Brasil tinha horário de verão e em 2023 não temos mais. O UTC+0 de 21/01/2013 12h52 seria 21/01/2023 16h52.
A partir daqui, a situação fica um pouco mais complicada. O calendário gregoriano se repete a cada 400 anos, uma vez que temos anos bissextos a cada 4 anos (os anos cujo número é divisível por 4) mas com três exceções, que a saber, são os anos divisíveis por 100 mas não por 400.
O Excel (tal como o ctgPi mencionou na resposta dele) usa como base o número de dias desde 01/01/1900, tendo as horas como parte fracionária. Curiosamente, este formato advém do paleozóico Lotus 1-2-3, que tinha um bug que fazia o ano de 1900 ser considerado bissexto e este bug existe no Excel até hoje (fonte). Corrigindo-se o bug, a data base dele passa a ser 31/12/1899. A implementação deste formato, seria parecida com a implementação acima dada para o timestamp do unix, apenas usando como base o ano de 1900 ao invés de 1970, trabalhando-se com números de ponto flutuante ao invés de inteiros, multiplicando-se/dividindo-se o timestamp por 86400 e dando-se um jeitinho no dia (que não existiu) 29 de fevereiro de 1900.
Como os SGBDs representam TIMESTAMP
(na realidade existem dois tipos, o TIMESTAMP WITH TIME ZONE
e o TIMESTAMP WITHOUT TIME ZONE
) é um detalhe de implementação, e portanto é difícil responder a sua pergunta sem saber exatamente qual SGBD você tem em mente (apesar da maioria simplesmente guardar uma data/hora com precisão de microsegundo), mas duas pegadinhas importantes são:
Se pegarmos o horasUnix
e dividirmos por 24, o quociente da divisão (vamos denominá-lo de diasUnix
) será o número de dias desde o ponto zero. O resto será a quantidade de horas transcorridas no dia. Para valores negativos de horasUnix
, aonde o quociente é zero ou negativo e o resto é negativo (mas não zero), deve-se somar 24 ao resto obtido e subtrair 1 do quociente obtido.
Various programming languages have different ways of converting a Unix timestamp. A timestamp's default format in Java might be different than a timestamp's default format in Python, and each language has different ways of calling those timestamps.