在我的Ruby应用程序中,我有一个Investment
实体,其term
属性。
我需要此类以3 Years
或36 months
的形式接受来自用户输入的字符串。我想要的是然后将输入转换为月数,将term
属性设置为此期间并计算出到期日。
到目前为止,我已尝试使用Active Support和Chronic,但API不支持此功能。
这个getter有效:
def term
if term =~ /year[s]?/i
term = term.to_i * 12
else term =~ /month[s]?/i
term = term.to_i
end
end
但是在Ruby中有更优雅的方法吗?
答案 0 :(得分:1)
如果我们可以假设输入字符串将始终包含一个或多个数字,后跟一个单位(“年”,“年”,“月”等),这非常简单。只需编写一个捕获数字和单位的正则表达式,将数字转换为数字并对单位进行标准化,然后进行数学运算。
def to_months(str)
if str =~ /(\d+)\s*(month|year)s?/i
num = $1.to_i # => 3
unit = $2.downcase # => year
num *= 12 if unit == "year"
return num
end
raise ArgumentError, "Invalid input"
end
puts to_months("3 Years") # => 36
puts to_months("1 month") # => 1
puts to_months("6months") # => 6
它不比你的方法更优雅,但也许它会给你一个或两个想法。
答案 1 :(得分:1)
Ruby并没有任何内置代表时间跨度的东西" (其他一些语言)。但是,有一个library for it (timespan
),虽然对你的情况可能有点矫枉过正。
您提到chronic
并不支持此功能。但为什么不自己计算时差?
require 'chronic'
input = '2 years'
then = Chronic.parse(input + ' ago')
now = Time.now
# Now we just calculate the number of months
term = (now.year * 12 + now.month) - (then.year * 12 + then.month)
这样,您就可以灵活地进行chronic
解析,但您仍然不需要太多代码。
或者继续使用timespan
库。
require 'timespan'
term = Timespan.new('2 years').to_months
# Boom.