如何将简单时间字符串解析为时间段?

时间:2014-10-14 17:19:57

标签: ruby datetime

在我的Ruby应用程序中,我有一个Investment实体,其term属性。

我需要此类以3 Years36 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中有更优雅的方法吗?

2 个答案:

答案 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.