Comment convertir un timestamp unix (secondes depuis l'époque) en Ruby DateTime?

comment convertir un timestamp Unix (secondes depuis l'époque) en Ruby DateTime?

318
demandé sur Johannes Hoff 2011-10-19 07:55:46

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')
302
répondu steenslag 2015-10-04 12:31:10

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>
572
répondu Adam Eberlin 2016-04-06 02:12:34

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****

46
répondu WattsInABox 2017-05-30 20:02:46

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"
7
répondu Tejasvi Manmatha 2014-02-12 15:53:21

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)

1
répondu sbutterworth 2015-09-05 03:42:48

si vous voulez juste une Date, vous pouvez faire Date.strptime(invoice.date.to_s, '%s')invoice.date vient sous la forme d'un Fixnum et puis converti en un String .

0
répondu pjammer 2013-10-10 18:25:09