Comment convertir un timestamp unix (secondes depuis l'époque) en Ruby DateTime?
comment convertir un timestamp Unix (secondes depuis l'époque) en Ruby DateTime?
6 réponses
DateTime.strptime
peut supporter des secondes depuis l'époque. Le numéro doit être converti en chaîne:
require 'date'
DateTime.strptime("1318996912",'%s')
Désolé, bref moment d'échec synaptique. Voici la vraie réponse.
require 'date'
Time.at(seconds_since_epoch_integer).to_datetime
bref exemple (qui tient compte du fuseau horaire du système actuel):
$ 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)>
nouvelle mise à jour (pour 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)>
mise à jour récente : j'ai comparé les meilleures solutions dans ce fil tout en travaillant sur un service HA il ya une semaine ou deux, et a été surpris de constater que Time.at(..)
dépasse DateTime.strptime(..)
(mise à jour: Ajout d'autres 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>
Le Temps De La Zone De Manutention
je veux juste clarifier, même si cela a été commenté afin que les futurs gens ne manquent pas cette distinction très importante.
DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000
affiche une valeur de retour en UTC et exige que les secondes soient une chaîne et affiche un objet UTC Time, tandis que
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
affiche une valeur de retour dans le fuseau horaire LOCAL, nécessite normalement un argument FixNum, mais le L'objet temps lui-même est toujours en UTC même si l'affichage ne l'est pas.
donc, même si j'ai passé le même entier aux deux méthodes, Je apparemment deux résultats différents en raison de la façon dont la classe' #to_s
méthode fonctionne. Cependant, comme @Eero a dû me le rappeler à deux reprises:
Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true
Une comparaison d'égalité entre les deux valeurs de retour renvoie toujours vrai. Encore une fois, c'est parce que les valeurs sont fondamentalement les mêmes (bien que la La méthode #==
s'occupe de cela pour vous), mais la méthode #to_s
imprime des chaînes radicalement différentes. Bien que, si nous regardons les chaînes, nous pouvons voir qu'elles sont en effet la même heure, juste imprimées dans des fuseaux horaires différents.
Argument D'Une Méthode De Clarification
les docs disent aussi" si un argument numérique est donné, le résultat est en heure locale."qui fait sens, mais était un peu confus pour moi, parce qu'ils n' donnez des exemples d'arguments non-entiers dans les docs. Ainsi, pour certains exemples d'arguments non-integer:
Time.at("1318996912")
TypeError: can't convert String into an exact number
vous ne pouvez pas utiliser un argument String, mais vous pouvez utiliser un argument Time dans Time.at
et il retournera le résultat dans le fuseau horaire de l'argument:
Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900
****édité à ne pas être complètement et totalement incorrectes dans tous les sens****
une commande pour convertir l'Heure de la date au format Unix et ensuite à la chaîne de caractères
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
enfin strftime est utilisé pour formater la date
exemple:
irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
"10 09 14"
indique la date du nombre de secondes dans le futur à partir du moment où vous exécutez le code.
time = Time.new + 1000000000 #date in 1 billion seconds
puts(temps)
selon l'heure actuelle je réponds à la question qu'il imprime 047-05-14 05:16:16 +0000
(1 milliard de secondes dans le futur)
ou si vous voulez compter des milliards de secondes à partir d'un moment donné, c'est au format Time.mktime(year, month,date,hours,minutes)
time = Time.mktime(1987,8,18,6,45) + 1000000000
puts ("je serais 1 milliard secondes sur: "+temps)
si vous voulez juste une Date, vous pouvez faire Date.strptime(invoice.date.to_s, '%s')
où invoice.date
vient sous la forme d'un Fixnum
et puis converti en un String
.