2010-11-12 23 views
11

Ruby的日期/時間助手很有用,但我發現有差異。看起來12個月不等於1年。檢查一個月,你會發現它等於30天,當然,12 * 30天= 360天,比實際年長度短5.25天。在Ruby中,12個月!= 1.year

當我根據客戶指定的授予月數設置對我們網站的某些組件的訪問權限時,我遇到了這個問題。我發現在運行我的測試時,一個月的36.個學期提前幾個星期就過期了。解決的辦法是這樣的:

def months_to_seconds(number_of_months) 
    ((number_of_months.to_f/12) * 1.year).to_i.seconds 
end 

這將返回在任何一年的分數是由NUMBER_OF_MONTHS代表的秒數。

由於1.年與365.25天相等,爲什麼你認爲他們沒有1.月回報一年中1/12而不是30天?

有沒有人跑過這個呢?有沒有人有更好的解決方案?

+3

不相關,但你不需要那裏的'to_f'調用;只需除以12.0。 – 2010-11-12 21:19:54

回答

24

日曆和時間總體來說是如此隨意的事情,並且充滿了這樣的不一致。沒有「月」的標準長度,因爲變化是在28天到31天之間的任何時間,正如沒有標準長度的「日」一樣,可以是23到25小時的任何時間,並且甚至分鐘可以有任何地方考慮到「閏秒」時59到62秒。同樣,一年可以是365或366天,或者是1582年的351次。

除非您針對特定時間間隔(如2010年1月3日至10月19日之間的秒數)進行了特定計算, 2011年,您將無法知道該時間間隔使用抽象月份,日期或年份的時間。這些事情取決於很多因素。

您的解決方案適合您的應用程序,但在Rails中,爲簡單起見,「月」僅爲30天,就像「24小時」一樣。

+3

+ 1。在爲我們的應用程序編寫一些邏輯時,我們遇到了與OP相似的問題。基本上你必須認識到,這些單位時間很不幸因爲它們的性質而不能排隊,所以如果你每週或每月都要進行轉換,那麼你只需要接受一些東西就可以了近似值並使用一致的轉換方法(例如,總是先轉換爲第幾天) – Jeremy 2010-11-12 22:12:23

+1

很遺憾,第二個甚至不再是一分鐘的1/60。 D那些銫原子,比光傳播快。 – 2010-11-12 23:28:04

0

1年由12個月組成,但其中幾個月是不同的大小。考慮到一個月實際上可能是28,29,30或31個日曆日,所以期望任何給定的一個月的長度可能不是人們想要的。

就個人而言,我在大多數情況下使用4周作爲一個月的定義。在這種情況下,如果您授予「一個月」的訪問權限,那麼我傾向於存儲授權訪問月份的日期。然後,取月號,並在當月N月的同一天過期。

+0

換句話說,不要使用每月的/ length /作爲任何事情;使用月份的數量。 – dannysauer 2010-11-12 21:32:20

0
require 'date' 

expire_date = Date.today >> 36 
puts expire_date #=> 2013-11-12 

如果你想減去幾個月,使用< <。

8

是的,沒有:

12 months是一樣的1 year當您使用它們作爲相對間隔,因爲他們不被轉換爲秒鐘,然後:

t = Time.now 
#=> 2010-11-12 22:34:57 0100 
t - 1.year == t - 12.months 
#=> true 

內部,這些間隔保持爲數組例如:

1.year - 12.months 
#=> 1 year and -12 months 

這意味着減法產生了一個間隔由「一年零12個月」組成。

但是,如果他們需要將它們轉換爲精確的秒數,並且有人決定「一個月」意味着「30天」,這與其他任何其他方式一樣好,但您堅持使用它。

這指出了文檔:

雖然這些方法在上面的 例子使用時提供精確的 計算,應小心 注意,這是不正確的,如果的 結果「月」,「年」,等被 使用

之前轉換我想這些時間間隔可以作爲一種方式「懶洋洋地評估」來看待。