270921sec를 일 + 시간 + 분 + 초로 변환하는 방법? (루비)
몇 초가 있습니다. 270921이라고합시다. xx 일, yy 시간, zz 분, ww 초라는 숫자를 어떻게 표시 할 수 있습니까?
다음을 사용하여 매우 간결하게 수행 할 수 있습니다 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
하지만, 코어 로직은 세 줄을 때이 과잉 될 수있다.
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"
Note that format_string
won't let you change the order of the parts (it's always the most significant value to least). For finer grained control, you can use split
and manipulate the values yourself.
Needed a break. Golfed this up:
s = 270921
dhms = [60,60,24].reduce([s]) { |m,o| m.unshift(m.shift.divmod(o)).flatten }
# => [3, 3, 15, 21]
Rails has an helper which converts distance of time in words. You can look its implementation: distance_of_time_in_words
If you're using Rails, there is an easy way if you don't need the precision:
time_ago_in_words 270921.seconds.from_now
# => 3 days
You can use the simplest method I found for this problem:
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
You can always adjust returned value to your needs.
2.2.2 :062 > formatted_duration 3661
=> "1 h 1 m 1 s"
I just start writing ruby. i guess this is only for 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
I modified the answer given by @Mike to add dynamic formatting based on the size of the result
def formatted_duration(total_seconds)
dhms = [60, 60, 24].reduce([total_seconds]) { |m,o| m.unshift(m.shift.divmod(o)).flatten }
return "%d days %d hours %d minutes %d seconds" % dhms unless dhms[0].zero?
return "%d hours %d minutes %d seconds" % dhms[1..3] unless dhms[1].zero?
return "%d minutes %d seconds" % dhms[2..3] unless dhms[2].zero?
"%d seconds" % dhms[3]
end
'programing' 카테고리의 다른 글
ctrl + shift + f를 사용하여 VSCode에서 선택한 코드를 들여 쓰거나 서식을 지정하는 방법 (0) | 2020.11.19 |
---|---|
MySQL과 Postgres 모두에 대해 대소 문자를 구분하지 않는 쿼리를 어떻게 작성합니까? (0) | 2020.11.19 |
MongoDB를 서비스로 시작할 수 없습니다. (0) | 2020.11.19 |
"실행 중"프로그램 편집? (0) | 2020.11.19 |
Android에서 새 활동을 시작하고 현재 활동을 완료 하시겠습니까? (0) | 2020.11.19 |