在 Ruby 中,12.个月!= 1.年

发布于 2024-10-02 08:22:18 字数 490 浏览 0 评论 0原文

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 天?

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

Ruby's date/time helpers are useful but I found a discrepancy. It seems that 12.months does not equal 1.year. Check 1.month and you'll find it's equal to 30.days and, of course, 12 * 30.days = 360.days, 5.25 days short of an actual year's length.

I came across this when I set access to certain components of our web site based on the number of months granted, as specified by the client. I discovered that a 36.month term expired a couple of weeks early when running my tests. The solution was something like this:

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

This returns the number of seconds in whatever fraction of a year is represented by the number_of_months.

Since 1.year is equal in seconds to 365.25 days, why do you suppose they didn't have 1.month return the seconds for 1/12 of a year instead of 30 days?

Has anyone run across this before? Does anyone have a better solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心意如水 2024-10-09 08:22:18

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

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

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

The calendar, and time in general, is such an arbitrary thing and is riddled with inconsistencies like this. There is no standard length of "month", as the variation is anywhere between 28 and 31 days, just as there is no standard length of "day", which can be anywhere from 23 to 25 hours, and even minute can have anywhere from 59 to 62 seconds when "leap seconds" are taken into account. Likewise a year can be 365 or 366 days, or even 351 as was the case in 1582.

Unless you're doing calculations specific to a particular interval, like the number of seconds between January 3, 2010 and October 19, 2011, you will not be able to know how long the interval is using abstract months, days, or years. These things are dependent on a huge number of factors.

Your solution is suitable for your application, but in Rails terms a "month" is simply 30 days for simplicity's sake, just as a "day" is 24 hours.

木槿暧夏七纪年 2024-10-09 08:22:18

是和否:

当您将它们用作相对间隔时,12 个月1 年 相同,因为它们不会转换为秒:那么:

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天”,这与其他任何近似值一样好,只要您坚持下去与它。

文档中指出了这一点:

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

我想这些间隔可以在某种程度上被视为“延迟评估”。

Yes and no:

12 months are the same as 1 year when you use them as relative intervals, because they are not converted to seconds then:

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

Internally, these intervals are kept as arrays of number of years, months and days, so if you say, for example:

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

it means that the subtraction resulted in an interval consisting of "one year and minus 12 months".

But if you to_i them, they need to be converted to exact amount of seconds, and someone decided that "a month" means "30 days", which is as good approximation as any other, while you stick with it.

That's pointed out in the docs:

While these methods provide precise
calculation when used as in the
examples above, care should be taken
to note that this is not true if the
result of 'months', 'years', etc is
converted before use

I guess these intervals can be looked at as "lazily evaluated" in a way.

耀眼的星火 2024-10-09 08:22:18

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

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

1 year is made up of 12 individual months, but several of those months are different sizes. Given that a month might actually be 28, 29, 30, or 31 calendar days, it's reasonable to expect that any given definition of the length of a month may not be what one wants.

Personally, I use 4 weeks as the definition of a month in most cases. In this case, where you're granting access for "a month", I'd be inclined to store the day of the month access was granted upon. Then, take the month number and put expiration on the same day of the month N month numbers later.

何以笙箫默 2024-10-09 08:22:18
require 'date'

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

如果要减去月份,请使用 << 。

require 'date'

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

If you want to subtract months, use << .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文