Ruby的日期/时间助手很有用,但我发现了一个差异。似乎12个月不等于1年。检查1.月,你会发现它等于30.days,当然,12 * 30.days = 360.days,比实际年份长5.25天。
当我根据客户指定的授权月数设置访问我们网站的某些组件时,我遇到了这种情况。我发现在运行我的测试时,一个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天的秒数?
以前有没有人碰过这个?有没有人有更好的解决方案?
答案 0 :(得分:24)
日历和时间一般都是如此随意,并且充满了这样的不一致。没有标准长度的“月”,因为变化在28到31天之间,正如没有标准长度的“日”,可以是23到25小时,甚至分钟可以有任何地方考虑“闰秒”时59到62秒。同样,一年可以是365或366天,甚至是1582年的351。
除非您正在针对特定时间间隔进行计算,例如2010年1月3日到2011年10月19日之间的秒数,否则您将无法知道时间间隔使用抽象月份,天数或年份。这些因素取决于很多因素。
您的解决方案适用于您的应用程序,但在Rails术语中,为简单起见,“月份”仅为30天,就像“白天”为24小时一样。
答案 1 :(得分:9)
是和否:
当您将它们用作相对间隔时, 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个月”。
但是如果你to_i
他们,他们需要被转换为精确的秒数,并且有人认为“一个月”意味着“30天”,这与任何其他的一样好,而你坚持用它。
文档中指出了这一点:
虽然这些方法提供了精确的 计算时用作 上面的例子,应该小心 要注意的是,如果这不是真的 “月”,“年”等的结果是 使用前转换
我猜这些间隔可以在某种程度上被视为“懒惰评估”。
答案 2 :(得分:0)
就个人而言,在大多数情况下,我使用4周作为一个月的定义。在这种情况下,如果您授予“一个月”访问权限,我倾向于存储授予访问权限的月份日期。然后,取月份数,并在一个月的同一天过期N个月数。
答案 3 :(得分:0)
require 'date'
expire_date = Date.today >> 36
puts expire_date #=> 2013-11-12
如果您想减去月数,请使用<<