Ruby将十进制持续时间(日|周|月|年)转换为结束日期

时间:2015-07-10 00:27:55

标签: ruby-on-rails ruby

我有start_at,小数quantityintervalday | week | month | year之一。

start_at = Time.parse('2016-01-01 00:00:00 UTC') # leap year
quantity = BigDecimal.new('1.998') # changed from 2.998, should end on 2/29/16 sometime
interval = 'month' # could be any of day|week|month|year

对于整数,我已经使用了1.month的持续时间,我看了Date#advance,虽然它只识别整数值。

看起来很简单但我在标准库或ActiveSupport中找不到任何东西。

参考文献:

问题

如何从小数点建立end_at日期?

为什么呢?目的是什么?

按给定间隔给出给定量的第二个。

期望

我正在寻找end_at到第二个尽可能准确的推进下一个interval(s)的小数{{1 }}。给定quantity,对于小数部分,当您通过月份的开头时,表示您当月interval = 'month'并使用它的持续时间。例如,2016年1月是31天,而2月(飞跃)是29天(仅在闰年)。

2 个答案:

答案 0 :(得分:2)

我想说你最好的选择是使用Ruby的日期方法根据小数的整数来提前计时,然后计算你的当前间隔的分数。

所以1.998个月,提前1个月。找到您当前所在的月份并获得该月份的秒数(即7月31x24x60x60x.998)的0.998,然后提前几秒钟。

答案 1 :(得分:1)

分数月的推进时间是什么意思?

假设我们有以下日期2015-01-01 00:00:00 UTC。我们很容易提前一个月完成,我们只需增加代表月份的数字:2015-02-01 00:00:00 UTC。或者,我们可以将此视为添加31天,我们知道这是1月份的天数。

但是,如果我们想从2015-01-01 00:00:00 UTC提前0.5个月呢?

我们不能像推进整整一个月那样增加。由于我们知道1月有31天,或许我们可以提前15.5天:2015-01-16 12:00:00 UTC。那种作品。

2015-01-01 00:00:00 UTC的1.5个月呢?如果我们结合以前的方法,我们首先递增,让我们向左前进0.5,然后2015-02-01 00:00:00 UTC。然后我们将28分的一半带到2015-02-15 00:00:00 UTC

但是等等,如果相反我们花了两个月之间的总天数然后花了3/4呢?像2(月)*(3/4),它将简化为(3(月))/ 2或1.5(月)。让我们试一试。

(28 days + 31 days) * 0.75 = 44.25 days

现在将其添加到2015-01-01 00:00:00 UTC,我们得到2015-02-14 06:00:00 UTC。那是我们其他答案的四分之三天。

这里的问题是一个月的长短不一。因此,部分月份并非始终可以确定。

想象一下,你有两个橘子。一个包含比另一个更多的果汁(可能是31毫升和29毫升的果汁)。你的食谱需要1.5个橙汁。根据你决定减少哪一个,你可以有44.5毫升或45.5毫升。但是,如果你的食谱需要40毫升的橙汁,你可以非常一致地测量它。很像你可以一直(有点)将日期增加40天。

时间真的很棘手。我们有闰秒,闰年,不一致的单位(月),时区,夏令时等......要考虑到。根据您的使用情况,您可能会尝试接近分数月,但我强烈建议您尝试避免处理分数月。