Jak przekonwertować uniksowy znacznik czasu (sekundy od epoki) na Ruby DateTime?

Jak przekonwertować uniksowy znacznik czasu (sekundy od epoki) na Ruby DateTime?

Author: Johannes Hoff, 2011-10-19

6 answers

DateTime.strptime może obsługiwać sekundy od epoki. Liczba musi być przekonwertowana na ciąg znaków:

require 'date'
DateTime.strptime("1318996912",'%s')
 302
Author: steenslag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-04 12:31:10

Przepraszam, krótka chwila awarii synapsy. Oto prawdziwa odpowiedź.

require 'date'

Time.at(seconds_since_epoch_integer).to_datetime

Krótki przykład (uwzględnia bieżącą strefę czasową systemu):

$ 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)> 

Dalsze aktualizacje (dla 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)>

Ostatnia aktualizacja: porównałem najlepsze rozwiązania w tym wątku podczas pracy nad usługą HA tydzień lub dwa temu i byłem zaskoczony, że Time.at(..) przewyższa DateTime.strptime(..) (aktualizacja: Dodano więcej benchmarków).

# ~ % 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
Author: Adam Eberlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-06 02:12:34

Obsługa Stref Czasowych

Chcę tylko wyjaśnić, mimo że zostało to skomentowane, aby przyszli ludzie nie przegapili tego bardzo ważnego rozróżnienia.

DateTime.strptime("1318996912",'%s') # => Wed, 19 Oct 2011 04:01:52 +0000

Wyświetla zwracaną wartość w UTC i wymaga, aby sekundy były ciągiem znaków i wyprowadza obiekt czasu UTC, podczas gdy

Time.at(1318996912) # => 2011-10-19 00:01:52 -0400

Wyświetla wartość zwracaną w lokalnej strefie czasowej, zwykle wymaga argumentu FixNum, ale sam obiekt czasu jest nadal w UTC, mimo że wyświetlacz nie jest.

Więc mimo, że przekazałem tę samą liczbę całkowitą do obu metod, pozornie dwa różne wyniki ze względu na to, jak działa metoda class' #to_s. Jednak jak @Eero musiał mi przypomnieć dwa razy:

Time.at(1318996912) == DateTime.strptime("1318996912",'%s') # => true

Porównanie równości między dwoma wartościami zwracanymi nadal zwraca true. Ponownie, dzieje się tak dlatego, że wartości są zasadniczo takie same (chociaż różne klasy, metoda #== zajmuje się tym za ciebie), ale metoda #to_s drukuje drastycznie różne ciągi. Chociaż, jeśli spojrzymy na ciągi, widzimy, że są rzeczywiście w tym samym czasie, TYLKO wydrukowane w różnych strefach czasowych.

Wyjaśnienie Argumentu Metody

Dokumenty mówią również: "jeśli podano argument liczbowy, wynik jest w czasie lokalnym."co ma sens, ale było dla mnie trochę mylące, ponieważ nie podają żadnych przykładów argumentów nie-całkowitych w dokumentach. Tak więc, dla niektórych przykładów nie-całkowitych argumentów:

Time.at("1318996912")
TypeError: can't convert String into an exact number

Nie możesz użyć argumentu String, ale możesz użyć argumentu Time do Time.at i zwróci wynik w strefie czasowej argumentu:

Time.at(Time.new(2007,11,1,15,25,0, "+09:00"))
=> 2007-11-01 15:25:00 +0900

****edytowane, aby nie być całkowicie i całkowicie niepoprawne pod każdym względem * * * *

 46
Author: WattsInABox,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-30 20:02:46

Jedno polecenie do konwersji czasu daty do formatu Unix, a następnie do 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

Wreszcie strftime jest używany do formatowania daty

Przykład:

    irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
    "10 09 14"
 7
Author: Tejasvi Manmatha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-12 15:53:21

To informuje o dacie liczby sekund w przyszłości od momentu wykonania kodu.

time = Time.new + 1000000000 #date in 1 billion seconds

Puts (time)

Zgodnie z aktualnym czasem odpowiadam na pytanie, które drukuje 047-05-14 05:16:16 +0000 (1 miliard sekund w przyszłości)

Lub jeśli chcesz policzyć miliard sekund z określonego czasu, jest to w formacie Time.mktime(year, month,date,hours,minutes)

time = Time.mktime(1987,8,18,6,45) + 1000000000

Puts ("I would be 1 Billion seconds old on:" +time)

 1
Author: sbutterworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-05 03:42:48

Jeśli chcesz tylko datę, można zrobić Date.strptime(invoice.date.to_s, '%s') gdzie invoice.date przychodzi w formie Fixnum, a następnie przekształcony na String.

 0
Author: pjammer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-10 18:25:09