2013-04-12 39 views
1

我有一個表示秒的浮點數。所以,我可以有38.93秒。如果可能的話,我正在尋找「最紅」的方法來獲得小時數,或者如果小時不可能,並且如果幾分鐘和幾小時不可能只有幾秒鐘,那麼分鐘就是幾分鐘。當我說可能的時候,我的意思是:將秒(浮點)轉換爲小時/秒/分

如果小於3600秒,它將是分鐘或秒。如果少於60秒,那將是秒。

現在我做了幾個如果看到它應該是什麼,但我認爲可能有一個更清潔的方式。

if input > 3600 
    return input/3600, 'hours' 
elseif input < 3600 && input > 60 
    return input/60, 'minutes' 
else 
    return input, 'seconds' 

感謝

+0

38.93不是一個Fixnum。 –

+0

大衛,對不起我的意思是浮動 –

回答

-1
input = 4000 #input in seconds 
h = {(60..3599) => ["input/60",'Minutes'], (0..59) => ["input",'Seconds'],(3600..Float::INFINITY) => ["input/3600",'Hours']} 
h.each_pair {|k,v| p "#{v.last} is #{eval(v.first)}" if k.include? input} 

input = 1100 #input in seconds 
h = {(60..3599) => ["input/60",'Minutes'], (0..59) => ["input",'Seconds'],(3600..Float::INFINITY) => ["input/3600",'Hours']} 
h.each_pair {|k,v| p "#{v.last} is #{eval(v.first)}" if k.include? input} 

input = 14 #input in seconds 
h = {(60..3599) => ["input/60",'Minutes'], (0..59) => ["input",'Seconds'],(3600..Float::INFINITY) => ["input/3600",'Hours']} 
h.each_pair {|k,v| p "#{v.last} is #{eval(v.first)}" if k.include? input} 

輸出:

"Hours is 1" 
"Minutes is 18" 
"Seconds is 14" 
+0

這看起來很好,但我只想返回「小時」或「分鐘」或「秒」,而不是他們三個 –

+0

@HommerSmith我更新了我的代碼。希望你喜歡它。 –

5

恕我直言與範圍的情況下,聲明將是一個有點清潔:

def some_method_name(input) 
    case input 
    when 0...60 
    input, 'seconds' 
    when 60...3600 
    input/60, 'minutes' 
    else 
    input/3600, 'hours' 
    end 
end 

另一個Appro公司ACH將是第一次提取小時,分鐘和秒:

def some_method_name(input) 
    hours, seconds = input.divmod(3600) 
    minutes, seconds = seconds.divmod(60) 

    if hours > 0 
    hours, 'hours' 
    elsif minutes > 0 
    minutes, 'minutes' 
    else 
    seconds, 'seconds' 
    end 
end 

軌之內,你當然會使用內置的pluralization

1

該方法的優點是能夠靈活指定所需的單位間隔。如果您願意,可以很容易地添加幾周,大約幾個月,幾年。它還修復了奇異值的複數形式。

TimeInt = Struct.new :name, :secs 
INTERVALS = [ TimeInt[:days, 60*60*24], TimeInt[:hours, 60*60], 
       TimeInt[:minutes, 60], TimeInt[:seconds, 1] ] 

def time_with_adaptive_units(secs) 
    ti = INTERVALS.find { |ti| secs >= ti.secs } || INTERVALS.last 
    val, name = (secs.to_f/ti.secs).round, ti.name.to_s 
    name.sub!(/s$/,'') if val == 1 
    "#{val} #{name}" 
end 

[5] pry(main)> time_with_adaptive_units(1) 
=> "1 second" 
[6] pry(main)> time_with_adaptive_units(45) 
=> "45 seconds" 
[7] pry(main)> time_with_adaptive_units(450) 
=> "7 minutes" 
[8] pry(main)> time_with_adaptive_units(4500) 
=> "1 hour" 
[9] pry(main)> time_with_adaptive_units(45000) 
=> "12 hours" 
[10] pry(main)> time_with_adaptive_units(450000) 
=> "5 days" 
+0

這很好!我應該在哪裏定義Struct?使用Rails,我想把這個方法放在ApplicationHelper中。如果我在方法本身中定義結構,我會得到一個「動態常量賦值」錯誤。 –

+0

@HommerSmith如果這是您唯一使用它的地方,我會在方法定義的上方定義Struct和INTERVALS。這只是一個讓INTERVALS數據自標籤的小夥伴。 – dbenhur

+0

我的一個怎麼樣? :) –

0

有什麼我能想到的:

total_seconds = 23456 
intervals = [3600, 60, 1].inject({rem: total_seconds, parts:[]}) do |memo, factor| 
    count = (memo[:rem]/factor).floor 
    memo[:rem] = memo[:rem] - (count * factor) 
    memo[:parts] << count 
    memo 
end 

而且你可以用

itervals[:parts].zip(['hours', 'minutes', 'seconds']).map{|p| p.join(' ')}.join(', ') 

完成它,你也可以看到,它是微不足道的這個擴大到數天,數週,幾個月,幾年,幾十年和幾個世紀,如果你想:D