Как да конвертирате unix timestamp (секунди от една епоха) в Ruby DateTime?

Как да конвертирате Unix timestamp (секунди от една епоха) в Ruby DateTime?

283
19 окт. Tronathan е даден на 19 октомври. 2011-10-19 06:55 '11 в 6:55 2011-10-19 06:55
@ 6 отговора

DateTime.strptime може да обработва секунди от една ера. Номерът трябва да се преобразува в низ:

 require 'date' DateTime.strptime("1318996912",'%s') 
266
19 окт. отговори на steenslag на 19 октомври 2011-10-19 12:35 '11 в 12:35 2011-10-19 12:35

Съжалявам, кратък момент от провал на синапса. Тук е истинският отговор.

 require 'date' Time.at(seconds_since_epoch_integer).to_datetime 

Кратък пример (това отчита текущата системна часова зона):

 $ 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)> 
border=0

Допълнителна актуализация (за 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)> 

Скорошна актуализация . Проверих най-добрите решения в тази нишка, работейки по HA услуга преди седмица или две, и бях изненадан, че Time.at(..) превъзхожда DateTime.strptime(..) (актуализация: добавени са повече бенчмарки).

 # ~ % 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> 
530
19 окт. отговорът е даден от Адам Еберлин на 19 октомври. 2011-10-19 06:56 '11 в 6:56 2011-10-19 06:56

Обработка на часови зони

Искам само да изясня, въпреки че това беше коментирано, така че бъдещите хора не пропускат това много важно разграничение.

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

показва връщаната стойност в UTC формат и изисква секунди да бъдат низ и да извеждат UTC времеви обект, докато

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

показва връщаната стойност в LOCAL часовата зона, обикновено е необходим аргументът FixNum, но самият времеви обект е все още в UTC, дори ако дисплеят липсва.

Така че, въпреки че предавах едно и също число за двата метода, очевидно имам два различни резултата, поради това как #to_s методът на клас #to_s . Въпреки това, тъй като @Eero трябваше да ми напомня два пъти:

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

Сравняването на равенствата между двете върнати стойности все пак връща вярно. Отново, това е така, защото стойностите са едни и същи (въпреки че методът на друг клас, #== ще се погрижи за това за вас), но методът #to_s отпечатва много различни низове. Въпреки че, ако погледнем редовете, можем да видим, че те са наистина едно и също време, отпечатани в различни часови зони.

Определение на аргумента за метода

Документите също така казват: "Ако е даден цифрен аргумент, резултатът ще бъде местно време." което има смисъл, но малко смущаващо, защото те не дават примери за аргументи, които не са цели числа в документи. Така че за някои примери за аргумент без число:

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

не можете да използвате аргумента String, но можете да използвате аргумента Time в Time.at и той ще върне резултата в часовата зона на аргумента:

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

****, редактиран, за да не бъде напълно и напълно погрешно във всички отношения ****

34
17 окт. отговор, даден WattsInABox 17 октомври. 2013-10-17 18:26 '13 в 18:26 2013-10-17 18:26

Една команда за преобразуване на датата във формат Unix и след това в низ

  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 

Накрая, strftime се използва за форматиране на датата

например:

  irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y") "10 09 14" 
6
12 февр. Отговорът е даден от Tejasvi Manmatha на 12 февруари. 2014-02-12 18:53 '14 в 18:53 2014-02-12 18:53

Това е датата на броя на секундите в бъдеще след изпълнението на кода.

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

поставя (време)

в съответствие с текущото време отговарям на въпроса, който отпечатва 047-05-14 05:16:16 +0000 (1 млрд. секунди в бъдеще)

или ако искате да изчислите милиарди секунди от определено време, това е във Time.mktime(year, month,date,hours,minutes)

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

поставя ("Бих 1 млрд. секунди при:" + време)

1
05 сент. Отговор, даден от sbutterworth Sep 05 2015-09-05 06:36 '15 в 6:36 AM 2015-09-05 06:36

Ако се нуждаете само от дата, можете да създадете Date.strptime(invoice.date.to_s, '%s') , където invoice.date е във формата Fixnum , а след това да се преобразува в String .

0
10 окт. отговор, даден от pjammer 10 октомври 2013-10-10 21:25 '13 в 21:25 2013-10-10 21:25

Други въпроси относно маркерите или Задайте въпрос