2015-12-17 28 views
2

我有一個跟蹤每個週期容量的應用程序(其中一個週期是激活的幾個月)。例如:使用Ruby/Rails查找當前週期的容量

  • 2015年1月29日中午12:00 - 2015年2月28日下午12時00分(週期#1)
  • 2015年2月28日中午12:00 - 2015年3月29日下午12時00分(週期# 2)
  • 2015年3月29日12:00 PM - 2015年4月29日下午12:00(週期#3)
  • ...

被跟蹤的一條信息是 '激活' 日期(即初始週期的開始)。有一個很好的方法來計算給定日期的週期(範圍)嗎?我目前的執行工作,但似乎浪費(不必循環到日期):

def period(activated, time) 
    cycles = 0 
    cycles = cycles.next while activated + cycles.next.months < time 
    return (activated + cycles.months)..(activated + cycles.next.months) 
end 
+0

是'activated''datetime'參數和時間是'時間'?或者兩者都是'datetime'?舉個例子,你現在試圖從'2015年1月29日12:00 PM'到'Apr 29,2015 12:00 PM'多少個週期? – user3097405

+0

'activated'和'time'都是時間對象。 'activated'是最初週期的開始。 '時間'是我試圖找到一個循環的時間。函數的結果是一個時間範圍(即2月28日,3月29日)。 – Stussa

回答

0

到Rails,1.month is 30.days,那麼確實,有一點數學,你可以做到這一點沒有所有的迭代:

def period(activated, time) 
    days = (time - activated).to_i 
    cycle_idx = days/30 
    cycle_start = activated + cycle_idx * 30 
    cycle_start..(cycle_start + 30) 
end 

讓我把它分解:

activated = DateTime.parse('Jan 29, 2015 12:00PM') # => #<DateTime: 2015-01-29T12:00:00+00:00 ...> 
time = DateTime.parse('Apr 15, 2015 6:00PM')  # => #<DateTime: 2015-04-30T12:00:00+00:00 ...> 

# Get the number of days between `activated` and `time`. 
days = (time - activated).to_i # => (305/4).to_i => 76 

# Divide by 30 to get the cycle number (0-based). 
cycle_idx = days/30 # => 2 

# Multiply the cycle number by 30 and add it to `activated` to get 
# the beginning of the cycle. 
cycle_start = activated + cycle_idx * 30 # => #<DateTime: 2015-03-30T12:00:00+00:00 ...> 

# Add 30 more to get the end of the cycle. 
cycle_start..(cycle_start + 30) 
# => #<DateTime: 2015-03-30T12:00:00+00:00 ...> 
# ..#<DateTime: 2015-04-29T12:00:00+00:00 ...> 

你會發現,像我一樣,是第3次循環開始於3月30日,而不是3月29日,與你的榜樣。據我所知,自2015年3月30日起爲2015年2月28日後30天,這與您的代碼得到的結果相同。

+0

'1.month'在Rails中不是**'30.days'。例如,從鐵軌控制檯嘗試: - 'Time.parse( 「2015年1月31日」)+ 1.month#二月28th' - 'Time.parse( 「2015年1月31日」)+ 2.months #三月31th' - 'Time.parse( 「2015年1月31日」)+ 3.months#四月30th' '1.month'實際上是一個'的ActiveSupport :: Duration'具有內置了一些花哨的功能用於處理時間/日期的添加。 –

+0

嗯。有趣。我在['Integer#months']中看到了'self * 30.days'(https://github.com/rails/rails/blob/ef5144d8a5529baebdaf76dbf253d1d6f2d8689b/activesupport/lib/active_support/core_ext/integer/time.rb#L20- L22)並取得了飛躍。你知道另一個解決方案可以滿足OP的用例嗎? –

0
def period(activated, time) 
    cycle = 1.month 
    # diff is how many cycles between activated and time 
    diff = ((time - activated)/1.month.second).floor 
    (activated + diff.months)..(activated + (diff.month + cycle)) 
end 
相關問題