Ответы:
DateTime.strptime
может справиться с секундами с эпохи. Число должно быть преобразовано в строку:
require 'date'
DateTime.strptime("1318996912",'%s')
%Q
.
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)>
Недавнее обновление : я тестировал лучшие решения в этой теме, работая над сервисом высокой доступности неделю или две назад, и был удивлен, обнаружив, что он 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
Сравнение равенства между двумя возвращаемыми значениями все еще возвращает 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,8 раза быстрее
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
чтобы убедиться, что времена равны, нет локальной метки времени, и в обоих случаях метка времени Unix интерпретируется как UTC. Time.at
представляет результирующий объект Time в местном часовом поясе и DateTime.strptime
представляет результирующий объект DateTime в UTC, но независимо от представления они равны, поскольку являются эквивалентным моментом времени.
Time.at(1318996912) # => 2011-10-19 00:01:52 -0400
утверждение отображает возвращаемое значение в местном часовом поясе, кажется, не является точным ... Можете ли вы проверить? Я полагаю, что ваше утверждение было бы правдой только в том случае, если бы вы использовали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
наконец, strftime используется для форматирования даты
Пример:
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
ставит («Мне было бы 1 миллиард секунд на:» + время)