我正在使用Rails 4,Ruby 2.1和PostgreSQL。
我有一个名为“duration”的数据库字段,它是一种间隔数据类型。
当提取此列中的数据时,它以hh:mm:ss的格式返回,例如01:30:00。
我正在试图找出一种方法来显示: 1小时30分钟
其他例子: 02:00:00至2小时 02:15:00至2小时15分钟 02:01:00到2小时1分钟
任何建议表示赞赏。
答案 0 :(得分:6)
我会从这样的事情开始:
def duration_of_interval_in_words(interval)
hours, minutes, seconds = interval.split(':').map(&:to_i)
[].tap do |parts|
parts << "#{hours} hour".pluralize(hours) unless hours.zero?
parts << "#{minutes} minute".pluralize(minutes) unless minutes.zero?
parts << "#{seconds} hour".pluralize(seconds) unless seconds.zero?
end.join(', ')
end
duration_of_interval_in_words('02:00:00')
# => '2 hours'
duration_of_interval_in_words('02:01:00')
# => '2 hours, 1 minute'
duration_of_interval_in_words('02:15:00')
# => '2 hours, 15 minutes'
答案 1 :(得分:0)
另见 ActionView :: Helpers :: DateHelper distance_of_time_in_words(及相关)
e.g。
0 <-> 29 secs # => less than a minute
30 secs <-> 1 min, 29 secs # => 1 minute
1 min, 30 secs <-> 44 mins, 29 secs # => [2..44] minutes
... etc
https://apidock.com/rails/ActionView/Helpers/DateHelper/distance_of_time_in_words
或许不适合包含在模型验证错误中? (这是我的用例)
答案 2 :(得分:0)
您可以尝试以下方法显示如下:
def minutes_to_human(minutes)
result = {}
hours = minutes / 60
result[:hours] = hours if hours.positive?
result[:minutes] = ((minutes * 60) - (hours * 60 * 60)) / 60 if minutes % 60 != 0
result[:minutes] /= 60.0 if result.key?(:hours) && result.key?(:minutes)
return I18n.t('helper.minutes_to_human.hours_minutes', time: (result[:hours] + result[:minutes]).round(2)) if result.key?(:hours) && result.key?(:minutes)
return I18n.t('helper.minutes_to_human.hours', count: result[:hours]) if result.key?(:hours)
return I18n.t('helper.minutes_to_human.minutes', count: result[:minutes].round) if result.key?(:minutes)
''
end
文:
en:
helper:
minutes_to_human:
minutes:
zero: '%{count} minute'
one: '%{count} minute'
other: '%{count} minutes'
hours:
one: '%{count} hour'
other: '%{count} hours'
hours_minutes: '%{time} hours'
答案 3 :(得分:0)
只需使用duration
+ inspect
seconds = 86400 + 3600 + 15
ActiveSupport::Duration.build(seconds).inspect
=> "1 day, 1 hour, and 15.0 seconds"
或者可以稍微自定义
ActiveSupport::Duration.build(seconds).parts.map do |key, value|
[value.to_i, key].join
end.join(' ')
=> "1days 1hours 15seconds"
P.S。
您可以获得秒数
1.day.to_i
=> 86400
时间只能以ISO8601格式解析
ActiveSupport::Duration.parse("PT2H15M").inspect
=> "2 hours and 15 minutes"
答案 4 :(得分:0)
这对我有用:
irb(main):030:0> def humanized_duration(seconds)
irb(main):031:1> ActiveSupport::Duration.build(seconds).parts.except(:seconds).reduce("") do |output, (key, val)|
irb(main):032:2* output+= "#{val}#{key.to_s.first} "
irb(main):033:2> end.strip
irb(main):034:1> end
=> :humanized_duration
irb(main):035:0> humanized_duration(920)
=> "15m"
irb(main):036:0> humanized_duration(3920)
=> "1h 5m"
irb(main):037:0> humanized_duration(6920)
=> "1h 55m"
irb(main):038:0> humanized_duration(10800)
=> "3h"
您可以更改您希望结果字符串在reduce 中的格式。我喜欢小时和分钟的“h”和“m”。我从持续时间部分排除了秒数,因为这对我的使用并不重要。
答案 5 :(得分:-1)
我发现duration.inspect非常适合这个目的。
> 10.years.inspect
=> "10 years"