Is there a gem or something to parse strings like "4h 30m" "1d 4h" -- sort of like the estimates in JIRA or task planners, maybe, with internationalization?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Posting a 2nd answer, as chronic (which my original answer suggested) doesn't give you timespans but timestamps.
Here's my go on a parser.
class TimeParser
TOKENS = {
"m" => (60),
"h" => (60 * 60),
"d" => (60 * 60 * 24)
}
attr_reader :time
def initialize(input)
@input = input
@time = 0
parse
end
def parse
@input.scan(/(\d+)(\w)/).each do |amount, measure|
@time += amount.to_i * TOKENS[measure]
end
end
end
The strategy is fairly simple. Split "5h"
into ["5", "h"]
, define how many seconds "h"
represents (TOKENS
), and add that amount to @time
.
TimeParser.new("1m").time
# => 60
TimeParser.new("1m wtf lol").time
# => 60
TimeParser.new("4h 30m").time
# => 16200
TimeParser.new("1d 4h").time
# => 100800
It shouldn't be too hard making it handle "1.5h"
either, seeing the codebase is as simple as it is.
回答2:
chronic_duration
does this.
回答3:
You can use chronic. It can parse pretty much everything you trhow at it, including "yesterday", "last week" etc.
Update: As the OP points out in the comment, Chronic is for dates, not timespans. See my other answer.
回答4:
I wrote this method that does it pretty well
def parse_duration(dur)
duration = 0
number_tokens = dur.gsub(/[a-z]/i,"").split
times = dur.gsub(/[\.0-9]/,"").split
if number_tokens.size != times.size
raise "unrecognised duration!"
else
dur_tokens = number_tokens.zip(times)
for d in dur_tokens
number_part = d[0].to_f
time_part = d[1]
case time_part.downcase
when "h","hour","hours"
duration += number_part.hours
when "m","minute","minutes","min","mins"
duration += number_part.minutes
when "d","day","days"
duration += number_part.days
when "w","week","weeks"
duration += number_part.weeks
when "month", "months"
duration += number_part.months
when "y", "year", "years"
duration += number_part.years
else
raise "unrecognised duration!"
end
end
end
duration
end
回答5:
Parse into what though?
This will parse into a Hash:
"4h 30m".split(/\s/).each{|i| h[i.gsub(/\d+/,"")] = i.gsub(/\w/,"")}
Sorry. not familiar with JIRA....