获取当前季度的月份数

时间:2011-06-12 13:20:53

标签: ruby-on-rails ruby

我需要一个包含当前季度月份数字的数组。我想提供Date.today然后得到例如。 [1,2,3]

我如何以最简单的方式做到这一点? (,使用switch / case)。

7 个答案:

答案 0 :(得分:6)

def quarter(date)
  1 + ((date.month-1)/3).to_i
end

答案 1 :(得分:4)

def quarter_month_numbers(date)
  quarters = [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]
  quarters[(date.month - 1) / 3]
end

答案 2 :(得分:2)

我建议按月建立一个索引的哈希:

@quarters_by_month = Hash[(1..12).map {|v| i=((v-1)/3)*3; [v,[i+1, i+2, i+3]]}]

然后任何未来的查询都只是

@quarters_by_month[month]

由于@ x3ro提到了CPU时间,我认为对所有提议的解决方案进行基准测试会很有趣,包括OP想要排除的case语句。结果如下:

> ruby jeebus.rb 
                     user     system      total        real
case_statement:  0.470000   0.000000   0.470000 (  0.469372)
quarter_month:   0.420000   0.000000   0.420000 (  0.420217)
solution1:       0.740000   0.000000   0.740000 (  0.733669)
solution2:       1.630000   0.010000   1.640000 (  1.634004)
defined_hash:    0.470000   0.000000   0.470000 (  0.469814)

以下是代码:

def case_statement(month)
  case month
  when 1,2,3
    [1,2,3]
  when 4,5,6
    [4,5,6]
  when 7,8,9
    [7,8,9]
  when 10,11,12
    [10,11,12]
  else
    raise ArgumentError
  end
end

def defined_hash(month)
  @quarters_by_month[month]
end

def solution1(month)
  (((month - 1) / 3) * 3).instance_eval{|i| [i+1, i+2, i+3]}
end

def solution2(month)
  [*1..12][((month - 1) / 3) * 3, 3]
end

def quarter_month_numbers(month)
  @quarters[(month - 1) / 3]
end


require 'benchmark'

n = 1e6

Benchmark.bm(15) do |x|
  x.report('case_statement:') do
    for i in 1..n do
      case_statement(rand(11) + 1)
    end 
  end

  x.report('quarter_month:') do
    @quarters = [[1,2,3], [4,5,6], [7,8,9], [10,11,12]]

    for i in 1..n do
      quarter_month_numbers(rand(11) + 1)
    end 
  end

  x.report('solution1:') do
    for i in 1..n do
      solution1(rand(11) + 1)
    end 
  end

  x.report('solution2:') do
    for i in 1..n do
      solution2(rand(11) + 1)
    end 
  end

  x.report('defined_hash:') do
    @quarters_by_month = Hash[(1..12).map {|v| i=((v-1)/3)*3; [v,[i+1, i+2, i+3]]}]

    for i in 1..n do
      defined_hash(rand(11) + 1)
    end
  end
end

答案 3 :(得分:1)

解决方案1 ​​

(((Date.today.month - 1) / 3) * 3).instance_eval{|i| [i+1, i+2, i+3]}

解决方案2

[*1..12][((Date.today.month - 1) / 3) * 3, 3]

答案 4 :(得分:1)

您可以执行以下操作:

m = date.beginning_of_quarter.month
[m, m+1, m+2]

以下在irb中展示:

>> date=Date.parse "27-02-2011"
=> Sun, 27 Feb 2011  
>> m = date.beginning_of_quarter.month
=> 1
>> [m, m+1, m+2]
=> [1, 2, 3]

我不知道这与其他方法相比有多快,也许@Wes也可以通过这种方式进行基准测试。

我认为这种方法的一个优点是代码的清晰度。这不是错综复杂的。

答案 5 :(得分:0)

看看这个小片段:

months = (1..12).to_a
result = months.map do |m|
  quarter = (m.to_f / 3).ceil
  ((quarter-1)*3+1..quarter*3).to_a
end

puts result.inspect

答案 6 :(得分:0)

Array

month    = Date.today.month # 6
quarters = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]
quarters.select { |quarter| quarter.include?(month) }
=> [[4, 5, 6]]

Hash

month    = Date.today.month # 6
quarters = {
  [1, 2, 3]    => 'First  quarter',
  [4, 5, 6]    => 'Second quarter',
  [7, 8, 9]    => 'Third  quarter',
  [10, 11, 12] => 'Fourth quarter',
}
quarters.select { |quarter| quarter.include?(month) }
=> {[4, 5, 6]=>"Second quarter"}

希望它有所帮助;)