Respostas:
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 de DateTime
. Portanto, use Time.strptime("1318996912345",'%Q').to_f
e você verá os milissegundos preservados, enquanto DateTime.strptime("1318996912345",'%Q').to_f
não o preserva.
Desculpe, breve momento de falha na sinapse. Aqui está a resposta real.
require 'date'
Time.at(seconds_since_epoch_integer).to_datetime
Breve exemplo (isso leva em consideração o fuso horário do sistema atual):
$ date +%s
1318996912
$ irb
ruby-1.9.2-p180 :001 > require 'date'
=> true
ruby-1.9.2-p180 :002 > Time.at(1318996912).to_datetime
=> #<DateTime: 2011-10-18T23:01:52-05:00 (13261609807/5400,-5/24,2299161)>
Atualização adicional (para UTC):
ruby-1.9.2-p180 :003 > Time.at(1318996912).utc.to_datetime
=> #<DateTime: 2011-10-19T04:01:52+00:00 (13261609807/5400,0/1,2299161)>
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(..)
supera DateTime.strptime(..)
(atualização: adicionamos mais benchmarks).
# ~ % ruby -v
# => ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-darwin13.0]
irb(main):038:0> Benchmark.measure do
irb(main):039:1* ["1318996912", "1318496912"].each do |s|
irb(main):040:2* DateTime.strptime(s, '%s')
irb(main):041:2> end
irb(main):042:1> end
=> #<Benchmark ... @real=2.9e-05 ... @total=0.0>
irb(main):044:0> Benchmark.measure do
irb(main):045:1> [1318996912, 1318496912].each do |i|
irb(main):046:2> DateTime.strptime(i.to_s, '%s')
irb(main):047:2> end
irb(main):048:1> end
=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>
irb(main):050:0* Benchmark.measure do
irb(main):051:1* ["1318996912", "1318496912"].each do |s|
irb(main):052:2* Time.at(s.to_i).to_datetime
irb(main):053:2> end
irb(main):054:1> end
=> #<Benchmark ... @real=1.5e-05 ... @total=0.0>
irb(main):056:0* Benchmark.measure do
irb(main):057:1* [1318996912, 1318496912].each do |i|
irb(main):058:2* Time.at(i).to_datetime
irb(main):059:2> end
irb(main):060:1> end
=> #<Benchmark ... @real=2.0e-05 ... @total=0.0>
Time.at
supere DateTime.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 disse
Tratamento 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.
DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000
exibe um valor de retorno em UTC e requer que os segundos sejam uma String e gera um objeto UTC Time, enquanto
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
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:
Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true
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:
Time.at("1318996912")
TypeError: can't convert String into an exact number
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:
Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900
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
09:10:58-watsw018:~$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
09:11:00-watsw018:~$ irb
irb(main):001:0> require 'benchmark'
=> true
irb(main):002:0> require 'date'
=> true
irb(main):003:0>
irb(main):004:0* format = '%s'
=> "%s"
irb(main):005:0> times = ['1318996912', '1318496913']
=> ["1318996912", "1318496913"]
irb(main):006:0> int_times = times.map(&:to_i)
=> [1318996912, 1318496913]
irb(main):007:0>
irb(main):008:0* datetime_from_strptime = DateTime.strptime(times.first, format)
=> #<DateTime: 2011-10-19T04:01:52+00:00 ((2455854j,14512s,0n),+0s,2299161j)>
irb(main):009:0> datetime_from_time = Time.at(int_times.first).to_datetime
=> #<DateTime: 2011-10-19T00:01:52-04:00 ((2455854j,14512s,0n),-14400s,2299161j)>
irb(main):010:0>
irb(main):011:0* datetime_from_strptime === datetime_from_time
=> true
irb(main):012:0>
irb(main):013:0* Benchmark.measure do
irb(main):014:1* 100_000.times {
irb(main):015:2* times.each do |i|
irb(main):016:3* DateTime.strptime(i, format)
irb(main):017:3> end
irb(main):018:2> }
irb(main):019:1> end
=> #<Benchmark::Tms:0x00007fbdc18f0d28 @label="", @real=0.8680500000045868, @cstime=0.0, @cutime=0.0, @stime=0.009999999999999998, @utime=0.86, @total=0.87>
irb(main):020:0>
irb(main):021:0* Benchmark.measure do
irb(main):022:1* 100_000.times {
irb(main):023:2* int_times.each do |i|
irb(main):024:3* Time.at(i).to_datetime
irb(main):025:3> end
irb(main):026:2> }
irb(main):027:1> end
=> #<Benchmark::Tms:0x00007fbdc3108be0 @label="", @real=0.33059399999910966, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.32000000000000006, @total=0.32000000000000006>
**** editado para não ser completamente e totalmente incorreto em todos os sentidos ****
**** benchmarks adicionados ****
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 e DateTime.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
DateTime.strptime(Time.now.utc.to_i.to_s,'%s').strftime("%d %m %y")
Time.now.utc.to_i #Converts time from Unix format
DateTime.strptime(Time.now.utc.to_i.to_s,'%s') #Converts date and time from unix format to DateTime
finalmente strftime é usado para formatar a data
Exemplo:
irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
"10 09 14"
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.
time = Time.new + 1000000000 #date in 1 billion seconds
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)
time = Time.mktime(1987,8,18,6,45) + 1000000000
puts ("Eu teria 1 bilhão de segundos em:" + hora)