【问题标题】:In Ruby, 12.months != 1.year在 Ruby 中,12.months != 1.year
【发布时间】:2010-11-12 21:17:06
【问题描述】:

Ruby 的日期/时间助手很有用,但我发现了一个差异。似乎 12.months 不等于 1.year。检查 1.month,您会发现它等于 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.year 等于 365.25 天的秒数,为什么你认为他们没有 1.month 返回一年中 1/12 的秒数而不是 30 天?

以前有人遇到过这个吗?谁有更好的解决方案?

【问题讨论】:

  • 不相关,但你不需要to_f 在那里打电话;只需除以12.0

标签: ruby-on-rails ruby date-math


【解决方案1】:

日历和一般的时间都是如此随意的东西,并且充斥着这样的不一致之处。 “月”没有标准长度,因为变化在 28 到 31 天之间,就像“天”没有标准长度一样,可以是 23 到 25 小时,甚至分钟也可以是考虑到“闰秒”时为 59 到 62 秒。同样,一年可以是 365 或 366 天,甚至是 351 天,就像 1582 年一样。

除非您正在针对特定时间间隔进行特定的计算,例如 2010 年 1 月 3 日到 2011 年 10 月 19 日之间的秒数,否则您将无法知道使用抽象月份、天数或年。这些事情取决于很多因素。

您的解决方案适合您的应用程序,但在 Rails 术语中,为简单起见,“月”只是 30 天,就像“天”是 24 小时一样。

【讨论】:

  • 为此加 1。在为我们的应用程序编写一些逻辑时,我们遇到了与 OP 类似的问题。基本上你必须意识到,不幸的是,这些时间单位由于它们的性质而不能对齐,所以如果你在每周、每月计算或其他东西之间进行转换,你只需要接受事情将是一个近似值并使用一致的转换方法(例如,始终先转换为天数)
  • 遗憾的是,一秒甚至不是一分钟的 1/60。甩开那些铯原子,比光速还快。
【解决方案2】:

是与否:

12 months1 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天”,这和其他任何人一样好近似,而你坚持它.

这是在文档中指出的:

虽然这些方法提供了精确的 在使用时计算 上面的例子,请注意 请注意,如果 “月”、“年”等的结果是 使用前转换

我猜这些区间在某种程度上可以被视为“懒惰评估”。

【讨论】:

    【解决方案3】:

    1 年由 12 个单独的月份组成,但其中有几个月份的大小不同。鉴于一个月实际上可能是 28、29、30 或 31 个日历日,因此可以合理地预期任何给定的一个月长度定义可能不是人们想要的。

    就我个人而言,在大多数情况下,我使用 4 周作为一个月的定义。在这种情况下,如果您授予“一个月”的访问权限,我倾向于存储授予访问权限的月份日期。然后,取月号,并在 N 月号后的一个月的同一天到期。

    【讨论】:

    • 换句话说,不要将月份的/length/用于任何事情;使用月份的数字。
    【解决方案4】:
    require 'date'
    
    expire_date = Date.today >> 36
    puts expire_date #=> 2013-11-12
    

    如果要减去月份,请使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-10
      • 2020-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-22
      相关资源
      最近更新 更多