Відповіді:
DateTime.strptime
може обробляти секунди з епохи. Номер повинен бути перетворений у рядок:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
tho.
Time
це потрібно замість цього DateTime
. Тож використовуйте, Time.strptime("1318996912345",'%Q').to_f
і ви побачите збережені мілісекунди, а DateTime.strptime("1318996912345",'%Q').to_f
не збережете їх.
Вибачте, короткий момент помилки синапсу. Ось справжня відповідь.
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)>
Подальше оновлення (для 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>
Time.at
перевершує DateTime.strptime
. Останній повинен розбирати рядок, який, як правило, набагато повільніше, ніж безпосередньо приймати число.
DateTime.strptime
оскільки він створює дві нові рядки, кожна ітерація, що дуже дорого. Це не просто розбір рядків, як сказав
Обробка часового поясу
Я просто хочу уточнити, хоча це було прокоментовано, щоб майбутні люди не пропустили цієї дуже важливої відзнаки.
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, але сам об’єкт Time все ще знаходиться в UTC, хоча дисплей це не так.
Отже, хоча я передав однакове ціле число обом методам, я, мабуть, два різні результати через те, як #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
Орієнтири
Після дискусії з @AdamEberlin щодо його відповіді я вирішив опублікувати трохи змінені орієнтири, щоб зробити все максимально рівним. Крім того, мені ніколи не хочеться знову будувати їх, щоб це було гарне місце, як і будь-яке, щоб зберегти їх.
Time.at (int) .to_datetime ~ 2.8x швидше
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>
**** відредаговано так, щоб не бути абсолютно та абсолютно невірним у всіх відношеннях ****
**** додано орієнтири ****
Time.at(1318996912) == DateTime.strptime("1318996912",'%s')
в часовому поясі без UTC, і ви побачите!
Time.use_zone "Samoa" do Time.at(1318996912) == DateTime.strptime("1318996912",'%s') end
щоб переконатися, що час однаковий, немає часової позначки LOCAL, і в обох випадках часова мітка Unix трактується як UTC. Time.at
представляє отриманий об’єкт Time у локальному часовому поясі та DateTime.strptime
представляє отриманий об’єкт DateTime в UTC, але незалежно від презентації вони рівні, оскільки є рівнозначним моментом часу.
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
відображає значення повернення у часовому поясі LOCAL , не видається точним ... Чи можете ви підтвердити це? Я вважаю, що ваше твердження було б правдивим лише в тому випадку, якщо ви використовувалиTime.zone.at(1318996912)
Одна команда для перетворення часу дати у формат 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
нарешті строповий текст використовується для форматування дати
Приклад:
irb(main):034:0> DateTime.strptime("1410321600",'%s').strftime("%d %m %y")
"10 09 14"
Time.now.utc.to_i
.
Це повідомляє про дату кількості секунд у майбутньому з моменту виконання коду.
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
put ("мені було б 1 мільярд секунд:" + час)