找到一个点的开始和结束范围

时间:2015-06-02 20:15:58

标签: ruby

我在这里创建了这个基础类:

class TimePeriod
  MONTHS_PER_QUARTER = 3
  QUARTER_RANGE = {
    0 => [1,3],
    1 => [4,6],
    2 => [7,9],
    3 => [10,12]
  }

  def self.quarter(month_num)
    (month_num - 1) / MONTHS_PER_QUARTER
  end

  def self.quarter_range(month_num)
    quarter = quarter month_num
    t1,t2 = QUARTER_RANGE[quarter]
    [Time.parse(Date::MONTHNAMES[t1]).beginning_of_month, Time.parse(Date::MONTHNAMES[t2]).end_of_month]
  end
end 

它为我提供了一个季度的时间范围,给定一个月作为整数提供:

> TimeUtils.quarter_range(Time.now.month)
 => [2015-04-01 00:00:00 -0400, 2015-06-30 23:59:59 -0400] 

所以它有效。但是,我欺骗了。我很难找到开始和结束,假设,比如说6个月。所以我硬编码了QUARTER_RANGE常量中的值。我希望能够删除那个QUARTER_RANGE常量并找到它的开头和结尾(例如[4,6])。

因此,例如,如果输入3(3月),6(6月),9(9月),12(12月)通过,我将使用模数算法知道它的季度结束:

3 % 3
=> 0
6 % 3
=> 0
9 % 3
=> 0
12 % 3
=> 0 

但令人抓狂的部分是让我们说5(5月),我怎么能回归[4,6]

4 个答案:

答案 0 :(得分:1)

(1..12).each do |m|
  low = 3*((m-1)/3) + 1
  p m, [low, low+2]
end

结果:

1
[1, 3]
2
[1, 3]
3
[1, 3]
4
[4, 6]
5
[4, 6]
6
...

答案 1 :(得分:1)

你可以像这样开始本季度的开始:

def qtr_start(mon)
  mon - (mon - 1) % MONTHS_PER_QUARTER
end

qtr_start(9) # => 7

本季度末只有两个:

def qtr_end(mon)
  qtr_start(mon) + 2
end

qtr_end(9) # => 9

把它们放在一起:

def qtr_start_end(mon)
  start = mon - (mon - 1) % MONTHS_PER_QUARTER
  [ start, start + 2 ]
end

(1..12).each do |mon|
  start_end = qtr_start_end(mon)
  puts "Month #{mon} is in quarter #{start_end.inspect}"
end

# => Month 1 is in quarter [1, 3]
#    Month 2 is in quarter [1, 3]
#    Month 3 is in quarter [1, 3]
#    Month 4 is in quarter [4, 6]
#    Month 5 is in quarter [4, 6]
#    Month 6 is in quarter [4, 6]
#    Month 7 is in quarter [7, 9]
#    Month 8 is in quarter [7, 9]
#    Month 9 is in quarter [7, 9]
#    Month 10 is in quarter [10, 12]
#    Month 11 is in quarter [10, 12]
#    Month 12 is in quarter [10, 12]

答案 2 :(得分:0)

好吧,我不确定你为什么要它,但是如果你想使用模数,这应该可以解决你想要的问题:

month = some_num
quarter_range = []
if month%3 == 0
  # end of quarter
  quarter_range = [month-2, month]
elsif month%3 == 1
  # beginning of quarter
  quarter_range = [month, month+2]
else
  # middle of quarter
  quarter_range = [month-1, month+1]
end

return quarter_range

答案 3 :(得分:0)

您可以执行以下操作:

MONTHS_PER_PERIOD = 3
PERIODS = (1..12).step(MONTHS_PER_PERIOD).map do |m|
   m..(m+MONTHS_PER_PERIOD-1)
end
  #=> [1..3, 4..6, 7..9, 10..12]

def month_to_period(m)
  PERIODS.find { |p| p.cover?(m) }
end

(1..12).each { |m| puts month_to_period(m) }
1..3
1..3
1..3
4..6
4..6
4..6
7..9
7..9
7..9
10..12
10..12
10..12

MONTHS_PER_PERIOD = 2
PERIODS = (1..12).step(MONTHS_PER_PERIOD).map do |m|
   m..(m+MONTHS_PER_PERIOD-1)
end
  #=> [1..2, 3..4, 5..6, 7..8, 9..10, 11..12] 

(1..12).each { |m| puts month_to_period(m) }
1..2
1..2
3..4
3..4
5..6
5..6
7..8
7..8
9..10
9..10
11..12
11..12