2013-10-25 30 views
18

Я ищу идиоматический способ получить время, прошедшее с данной даты в часах, минутах и ​​секундах.Rails - получить разницу во времени в часах, минутах и ​​секундах

Если заданная дата - 2013-10-25 23:55:00, а текущая дата - 2013-10-27 20:55:09, возвращаемая стоимость должна быть 45:03:09. С этим требованием не будут работать драгоценные камни time_difference и time_diff.

+0

Возможный дубликат [как конвертировать 270921сек в дни + часы + минуты + сек? (ruby)] (http://stackoverflow.com/questions/2310197/how-to-convert-270921sec-into-days-hours-minutes-sec-ruby) – maurice

ответ

31

Вы можете попробовать с этим:

def time_diff(start_time, end_time) 
    seconds_diff = (start_time - end_time).to_i.abs 

    hours = seconds_diff/3600 
    seconds_diff -= hours * 3600 

    minutes = seconds_diff/60 
    seconds_diff -= minutes * 60 

    seconds = seconds_diff 

    "#{hours.to_s.rjust(2, '0')}:#{minutes.to_s.rjust(2, '0')}:#{seconds.to_s.rjust(2, '0')}" 
    # or, as hagello suggested in the comments: 
    # '%02d:%02d:%02d' % [hours, minutes, seconds] 
end 

и использовать его :

time_diff(Time.now, Time.now-2.days-3.hours-4.minutes-5.seconds) 
# => "51:04:04" 
+0

Лучше использовать этот код или класс Benchmark для проведения бенчмаркинга (а просто подсчитайте время, необходимое для выполнения определенной работы)? – stack1

+1

Для этого вы должны использовать встроенные контрольные точки или драгоценный камень. «не изобретать велосипед» ;-) – MrYoshiji

+1

Разве это не означает, что «to_i» делает результирующее рациональное из вычитания как закругленное довольно много? Всякий раз, когда я его использую, я получаю «0» даже для вещей, которые заняли несколько минут. Кажется, вам кажется, что вам нужно использовать 'to_f', верно? – GlyphGryph

22
time_diff = Time.now - 2.minutes.ago 
Time.at(time_diff.to_i.abs).utc.strftime "%H:%M:%S" 
=> "00:01:59" 

Или, если ваше приложение требовательно округление, просто заменить to_i на раунд:

Time.at(time_diff.round.abs).utc.strftime "%H:%M:%S" 
    => => "00:02:00" 

Не уверен фразеологические части, хотя

Update: Если разница во время, как ожидается, будет более чем через 24 часа, указанный выше код неверен. Если дело обстоит именно так, можно было бы следовать ответ @MrYoshiji или отрегулировать выше раствора для расчета часов от объекта даты и времени вручную:

def test_time time_diff 
    time_diff = time_diff.round.abs 
    hours = time_diff/3600 

    dt = DateTime.strptime(time_diff.to_s, '%s').utc 
    "#{hours}:#{dt.strftime "%M:%S"}" 
end 

test_time Time.now - 28.hours.ago - 2.minutes - 12.seconds 
=> "27:57:48" 
test_time Time.now - 8.hours.ago - 2.minutes - 12.seconds 
=> "7:57:48" 
test_time Time.now - 24.hours.ago - 2.minutes - 12.seconds 
=> "23:57:48" 
test_time Time.now - 25.hours.ago - 2.minutes - 12.seconds 
=> "24:57:48" 
+0

не работает с 'time_diff = Time.now - 2 .days.ago', возвращается 23:59:59 – MrYoshiji

+0

Ну 1 секунда потеряна из-за округления. Вы можете изменить to_i вызов на раунд, если он имеет отношение к вашей логике приложения. – Tumas

+2

Это очень чистый, но он никогда не возвращает ничего за 24 часа. –

Смежные вопросы