2010-02-22 32 views

उत्तर

140

यह बहुत किया जा सकता है संक्षेप में divmod का उपयोग कर: आप इसके कार्यान्वयन देख सकते हैं

t = 270921 
mm, ss = t.divmod(60)   #=> [4515, 21] 
hh, mm = mm.divmod(60)   #=> [75, 15] 
dd, hh = hh.divmod(24)   #=> [3, 3] 
puts "%d days, %d hours, %d minutes and %d seconds" % [dd, hh, mm, ss] 
#=> 3 days, 3 hours, 15 minutes and 21 seconds 

आप शायद यह collect, या हो सकता है inject के साथ रचनात्मक हो रही द्वारा आगे सूख सकता है, लेकिन जब कोर तर्क है तीन लाइनें यह अधिक हो सकती है।

+0

@ माइक वुडहाउस: यही वह है जिसे मैं ढूंढ रहा था। धन्यवाद। – Radek

+1

महान उत्तर - धन्यवाद। –

+0

+1, अगर मुझे 90 मिनट तक सेकंड दिखाने की ज़रूरत है तो उदाहरण के लिए मैं एक गेम को ट्रैक कर रहा हूं। यह 90:54 की तरह कुछ दिखाना चाहिए। धन्यवाद! – uday

9

रेल के पास एक सहायक है जो शब्दों में समय की दूरी को परिवर्तित करता है। distance_of_time_in_words

+1

क्या रेल के बाहर इसका उपयोग करने का कोई तरीका है? – Kostas

+1

हां। एक्शन व्यू :: हेल्पर्स :: डेटहेल्पर शामिल करें! –

+1

a = distance_of_time_in_words (from_time, from_time + 50.minutes) => "लगभग 1 घंटा" 1.9.2-p290: 035> –

13

मैं वहाँ उम्मीद थी divmod का उपयोग करने से एक आसान तरीका होगा, लेकिन यह सबसे अधिक सूखी और पुन: प्रयोज्य तरह से मैं यह करने के लिए मिल गया है:

def seconds_to_units(seconds) 
    '%d days, %d hours, %d minutes, %d seconds' % 
    # the .reverse lets us put the larger units first for readability 
    [24,60,60].reverse.inject([seconds]) {|result, unitsize| 
     result[0,0] = result.shift.divmod(unitsize) 
     result 
    } 
end 

विधि आसानी से प्रारूप स्ट्रिंग को बदलने के द्वारा निकाला जाता है और पहली इनलाइन सरणी (यानी [24,60,60])।

बढ़ी संस्करण

class TieredUnitFormatter 
    # if you set this, '%d' must appear as many times as there are units 
    attr_accessor :format_string 

    def initialize(unit_names=%w(days hours minutes seconds), conversion_factors=[24, 60, 60]) 
    @unit_names = unit_names 
    @factors = conversion_factors 

    @format_string = unit_names.map {|name| "%d #{name}" }.join(', ') 
    # the .reverse helps us iterate more effectively 
    @reversed_factors = @factors.reverse 
    end 

    # e.g. seconds 
    def format(smallest_unit_amount) 
    parts = split(smallest_unit_amount) 
    @format_string % parts 
    end 

    def split(smallest_unit_amount) 
    # go from smallest to largest unit 
    @reversed_factors.inject([smallest_unit_amount]) {|result, unitsize| 
     # Remove the most significant item (left side), convert it, then 
     # add the 2-element array to the left side of the result. 
     result[0,0] = result.shift.divmod(unitsize) 
     result 
    } 
    end 
end 

उदाहरण:

fmt = TieredUnitFormatter.new 
fmt.format(270921) # => "3 days, 3 hours, 15 minutes, 21 seconds" 

fmt = TieredUnitFormatter.new(%w(minutes seconds), [60]) 
fmt.format(5454) # => "90 minutes, 54 seconds" 
fmt.format_string = '%d:%d' 
fmt.format(5454) # => "90:54" 

नोट format_string आप भागों के आदेश को बदल नहीं दूँगा कि (यह हमेशा कम से कम करने के लिए सबसे महत्वपूर्ण मूल्य है)। बेहतर अनाज नियंत्रण के लिए, आप split का उपयोग कर सकते हैं और मानों को स्वयं में कुशल बना सकते हैं।

2

मैं बस रूबी लिखना शुरू करता हूं। मैं लगता है कि यह केवल 1.9.3

def dateBeautify(t) 

    cute_date=Array.new 
    tables=[ ["day", 24*60*60], ["hour", 60*60], ["minute", 60], ["sec", 1] ] 

    tables.each do |unit, value| 
     o = t.divmod(value) 
     p_unit = o[0] > 1 ? unit.pluralize : unit 
     cute_date.push("#{o[0]} #{unit}") unless o[0] == 0 
     t = o[1] 
    end 
    return cute_date.join(', ') 

end 
9

के लिए है आप रेल उपयोग कर रहे हैं, वहाँ एक आसान तरीका है अगर आप परिशुद्धता की आवश्यकता नहीं है:

time_ago_in_words 270921.seconds.from_now 
# => 3 days 
+0

यह इंगित करने के लिए धन्यवाद कि रेलों में यह है – nXqd

10

एक को तोड़ने की जरूरत। इस golfed:

s = 270921 
dhms = [60,60,24].reduce([s]) { |m,o| m.unshift(m.shift.divmod(o)).flatten } 
# => [3, 3, 15, 21] 
4

आप सरलतम विधि मैं इस समस्या के लिए पाया का उपयोग कर सकते हैं:

def formatted_duration total_seconds 
    hours = total_seconds/(60 * 60) 
    minutes = (total_seconds/60) % 60 
    seconds = total_seconds % 60 
    "#{ hours } h #{ minutes } m #{ seconds } s" 
    end 

तुम हमेशा अपनी आवश्यकताओं के दिए गए मान समायोजित कर सकते हैं।

2.2.2 :062 > formatted_duration 3661 
=> "1 h 1 m 1 s" 
संबंधित मुद्दे