Рубин: Рассчитать разницу во времени между 2 раза
Я хочу рассчитать разницу между 2 раза. start_time: 22:00 (Rails интерпретирует это как 2015-12-31 22:00:00 +0100) second_time: 02:00 (Rails интерпретирует это как 2015-12-31 02:00:00 +0100). Второй раз спустя 4 часа, так что на следующий день. Есть ли способ рассчитать эту разницу?
Я не могу просто сделать это: second_time - first_time, потому что это дает мне разницу в 22 часа вместо 4 часов.
Изменить:некоторая справочная информация: работа начинается в 22:00 и заканчивается на следующий день в 02:00. Поскольку я заполняю форму этой работы только один раз, это время для двух вышеуказанных значений: 2015-12-31 22:00:00 +0100 и 2015-12-31 02:00:00 +0100. Я не хочу, чтобы пользователь указывал время, включая дату. Реальная разница между временем должна составлять 4 часа.
Так что я на самом деле хочу вычислить разницу между 22:00 и 02:00 (на следующий день).
3 ответа
Я не понимаю, почему вы думаете, что он должен вернуться через 4 часа или почему он возвращается через 22 часа. 20 часов будет правильным для вашего примера:
require 'time'
a = Time.parse('2015-12-31 22:00:00 +0100')
b = Time.parse('2015-12-31 02:00:00 +0100')
a - b
#=> 72000.0 # difference in seconds
(a - b) / 3600
#=> 20.0 # difference in hours
Обновление: похоже, что вы имеете дело только с частью времени, а не с фактической датой. И я предполагаю, что максимальная разница, с которой вам придется иметь дело, составляет 24 часа:
def time_difference(time_a, time_b)
difference = time_b - time_a
if difference > 0
difference
else
24 * 3600 + difference
end
end
a = Time.parse('2015-12-31 22:00:00 +0100')
b = Time.parse('2015-12-31 02:00:00 +0100')
time_difference(a, b) / 3600
# => 4 # hours
a = Time.parse('2015-12-31 02:00:00 +0100')
b = Time.parse('2015-12-31 22:00:00 +0100')
time_difference(a, b) / 3600
# => 20 # hours
Старый вопрос, но я сделал хороший способ справиться с этим:
def time(start,ending)
if start != ending
medidas=["year","month","day","hour","minute","second"]
array=[1970,1,1,0,0,0]
text = ""
Time.at(ending-start).utc.to_a.take(6).reverse.each_with_index do |k,i|
text = "#{text} #{I18n.translate medidas[i].to_sym, count: k-array[i]}"
end
text = text.strip.squish
pos = text.rindex(" ",(text.rindex(" ")-1))
unless pos.nil?
text = text.insert(pos," and")
end
text = text.strip.squish #This shouldn't be needed but just in case
else
"0 seconds"
end
end
Затем в config/locales/en.yml я добавил:
en:
año:
zero: ''
one: '1 year'
other: '%{count} years'
mes:
zero: ''
one: '1 month'
other: '%{count} months'
dia:
zero: ''
one: '1 day'
other: '%{count} days'
hora:
zero: ''
one: '1 hour'
other: '%{count} hours'
minuto:
zero: ''
one: '1 minute'
other: '%{count} minutes'
segundo:
zero: ''
one: '1 second'
other: '%{count} seconds'
Так, например, когда вы звоните:
start = Time.now
ending = start + (60*60)
time(start,ending)
=> "1 hour"
ending = start + (60*60*28)
time(start,ending)
=> "1 day and 4 hours"
ending = start + (53*60*5874)
time(start,ending)
=> "7 months 4 days 4 hours and 42 minutes"
Надеюсь, это полезно
Я бы написал это так (перед добавлением проверок данных), чтобы попытаться сделать это самодокументированным:
require 'time'
DT_FMT = '%Y-%m-%d %H:%M:%S %z'
SECONDS_PER_DAY = 24*60*60
def hours_elapsed(start_str, finish_str)
start = DateTime.strptime(start_str, DT_FMT).to_time
finish = DateTime.strptime(finish_str, DT_FMT).to_time
finish = same_time_tomorrow(finish) if finish < start
(finish-start)/3600
end
def same_time_tomorrow(time)
time + SECONDS_PER_DAY
end
hours_elapsed '2015-12-31 22:00:00 +0100', '2015-12-31 02:00:00 +0100'
#=> 4.0
hours_elapsed '2015-12-31 02:00:00 +0100', '2015-12-31 22:00:00 +0100'
#=> 20.0