2010-11-12 21 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天”,这与其他任何其他方式一样好,但您坚持使用它。

这指出了文档:

虽然这些方法在上面的 例子使用时提供精确的 计算,应小心 注意,这是不正确的,如果的 结果“月”,“年”,等被 使用

之前转换我想这些时间间隔可以作为一种方式“懒洋洋地评估”来看待。