Como você converte um carimbo de data / hora Unix (segundos desde a época) para Ruby DateTime?
369
DateTime.strptime
pode lidar com segundos desde a época. O número deve ser convertido em uma sequência:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
tho.Time
é necessário em vez deDateTime
. Portanto, useTime.strptime("1318996912345",'%Q').to_f
e você verá os milissegundos preservados, enquantoDateTime.strptime("1318996912345",'%Q').to_f
não o preserva.Desculpe, breve momento de falha na sinapse. Aqui está a resposta real.
Breve exemplo (isso leva em consideração o fuso horário do sistema atual):
Atualização adicional (para UTC):
Atualização recente : comparei as principais soluções neste segmento enquanto trabalhava em um serviço de alta disponibilidade há uma ou duas semanas e fiquei surpreso ao descobrir que
Time.at(..)
superaDateTime.strptime(..)
(atualização: adicionamos mais benchmarks).fonte
Time.at
supereDateTime.strptime
. O último tem que analisar uma string, que geralmente é muito mais lenta do que receber um número diretamente.DateTime.strptime
pois está criando duas novas Strings a cada iteração, o que é muito caro. Não é apenas a seqüência de analisar como @claw disseTratamento de fuso horário
Eu só quero esclarecer, mesmo que isso tenha sido comentado para que futuras pessoas não percam essa distinção muito importante.
exibe um valor de retorno em UTC e requer que os segundos sejam uma String e gera um objeto UTC Time, enquanto
exibe um valor de retorno no fuso horário LOCAL, normalmente requer um argumento FixNum, mas o próprio objeto Time ainda está no UTC, mesmo que a exibição não esteja.
Portanto, mesmo que eu tenha passado o mesmo número inteiro para os dois métodos, aparentemente tenho dois resultados diferentes por causa de como o
#to_s
método da classe funciona. No entanto, como o @Eero teve que me lembrar duas vezes:Uma comparação de igualdade entre os dois valores de retorno ainda retorna true. Novamente, isso ocorre porque os valores são basicamente os mesmos (embora classes diferentes, o
#==
método cuide disso para você), mas o#to_s
método imprime cadeias drasticamente diferentes. Embora, se olharmos para as strings, podemos ver que elas são de fato a mesma hora, apenas impressas em fusos horários diferentes.Método Argumento Esclarecimento
Os documentos também dizem "Se um argumento numérico for fornecido, o resultado será no horário local". o que faz sentido, mas foi um pouco confuso para mim porque eles não dão exemplos de argumentos não inteiros nos documentos. Portanto, para alguns exemplos de argumentos não inteiros:
você não pode usar um argumento String, mas pode usar um argumento Time
Time.at
e ele retornará o resultado no fuso horário do argumento:Benchmarks
Após uma discussão com o @AdamEberlin sobre sua resposta, decidi publicar benchmarks ligeiramente alterados para tornar tudo o mais igual possível. Além disso, nunca quero ter que construí-las novamente, para que este seja o melhor lugar para salvá-las.
Time.at (int) .to_datetime ~ 2.8x mais rápido
**** editado para não ser completamente e totalmente incorreto em todos os sentidos ****
**** benchmarks adicionados ****
fonte
Time.at(1318996912) == DateTime.strptime("1318996912",'%s')
em um fuso horário não UTC e você verá!Time.use_zone "Samoa" do Time.at(1318996912) == DateTime.strptime("1318996912",'%s') end
para verificar se os horários são iguais, se não existe um registro de data e hora LOCAL e, em ambos os casos, o registro de data e hora do Unix é interpretado como estando no UTC.Time.at
apresenta o objeto Time resultante no fuso horário local eDateTime.strptime
apresenta o objeto DateTime resultante no UTC, mas independentemente da apresentação, eles são iguais, pois são o momento equivalente no tempo.Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
exibe um valor de retorno no fuso horário LOCAL não parece ser precisa ... Você pode verificar? Acredito que sua declaração só seria verdade se você usouTime.zone.at(1318996912)
Um comando para converter data e hora no formato Unix e depois em string
finalmente strftime é usado para formatar a data
Exemplo:
fonte
Time.now.utc.to_i
.Isso informa a data do número de segundos no futuro a partir do momento em que você executa o código.
põe (hora)
de acordo com o horário atual, estou respondendo à pergunta impressa
047-05-14 05:16:16 +0000
(1 bilhão de segundos no futuro)ou se você quiser contar bilhões de segundos de um horário específico, está no formato
Time.mktime(year, month,date,hours,minutes)
puts ("Eu teria 1 bilhão de segundos em:" + hora)
fonte
Se você queria apenas uma Data, pode fazer de
Date.strptime(invoice.date.to_s, '%s')
ondeinvoice.date
vem na forma de umFixnum
e depois convertido em umString
.fonte
Time.at(1500923406).to_date.to_s
=>"2017-07-24"