红宝石日期减法(例如90天前)


88

我对joda-time API有点迷恋:

DateTime now = new DateTime();
DateTime ninetyDaysAgo = now.minusDays(90);

我正在尝试在Ruby中做类似的事情,但是我

now = Time.now
ninetyDaysAgo = now - (90*24)

但是,这里的数学运算是关闭的(我实际上是在午夜处理日期)。

是否有用于日期减法的友好API?

Answers:


103
require 'date'
now = Date.today
ninety_days_ago = (now - 90)

通过IRB控制台运行此命令,我得到:

>>require 'date'
now = Date.today
ninety_days_ago = (now - 90)

require 'date'
=> false
now = Date.today
=> #<Date: 2011-03-02 (4911245/2,0,2299161)>
ninety_days_ago = (now - 90)
=> #<Date: 2010-12-02 (4911065/2,0,2299161)>

如果您需要时间,您可以说 now = DateTime.now


您原来的帖子,预编辑的内容更接近我的需要,但Date.Now受了保护。Date.today工作。如果您将第一个内容更改为现在= Date.today,我会接受的。
darthtrevino

3
@Matt:如何减去90小时而不是几天?
Esteban Feldman'2

@EstebanFeldman Date还允许使用分数,因此您可以这样做Date.today - (90.0/24.0)。结果可容易地转化to_datetimeto_time太。
jchook

15

对于使用Rails的用户,请检查以下内容:

DateTime.now - 10.days
=> Sat, 04 May 2013 12:12:07 +0300

20.days.ago - 10.days
=> Sun, 14 Apr 2013 09:12:13 UTC +00:00

10

如果您正在使用Rails或不介意包含ActiveSupport,则可以使用Numeric#days DSL,如下所示:

ruby-1.9.2-p136 :002 > Date.today
 => Wed, 02 Mar 2011 
ruby-1.9.2-p136 :003 > Date.today - 90.days
 => Thu, 02 Dec 2010 

由于您使用的是日期而不是时间,因此,您也应该以Date实例开头,或者使用#to_date转换DateTime实例。从日期实例中添加/减去数字时,数字隐式为天。

ruby-1.9.2-p136 :016 > DateTime.now.to_date
 => #<Date: 2011-03-02 (4911245/2,0,2299161)> 
ruby-1.9.2-p136 :017 > DateTime.now.to_date - 90
 => #<Date: 2010-12-02 (4911065/2,0,2299161)> 

8

Ruby在Date和DateTime类中支持日期算术,这是Ruby标准库的一部分。这两个类都公开了#+#-方法,它们从日期或时间中增加或减少几天。

$ irb
 > require 'date'
 => true 
 > (DateTime.new(2015,4,1) - 90).to_s  # Apr 1, 2015 - 90 days
 => "2015-01-01T00:00:00+00:00"
 > (DateTime.new(2015,4,1) - 1).to_s   # Apr 1, 2015 - 1 day
 => "2015-03-31T00:00:00+00:00" 

使用#<<#>>方法可在数月而不是数天的时间内运行。数月的算术与数天的算术有点不同。使用Date代替DateTime可以使效果更加明显。

 > (Date.new(2015, 5, 31) << 3).to_s  # May 31 - 3 months; 92 days diff
 => "2015-02-28" 

在您的joda-time示例之后,您可以在Ruby中编写类似的内容。

now =  DateTime.now
ninety_days_ago = now - 90

也许只是

ninety_days_ago = DateTime.now - 90

5

这是一篇非常古老的文章,但是如果您想保留一个Time对象,就像最初询问的那样,而不是切换到一个Date对象,则可以考虑使用Ruby Facets

Ruby Facets是针对核心Ruby类的扩展的标准化库。

http://rubyworks.github.io/facets/

通过要求方面,您可以对时间对象执行以下操作。

Time.now.less(90, :days)


这个项目已经两年没有更新了,只发表了一条评论就打开了问题。死了
user4674453 '07年

@ user4674453最近更新是六个月前。这是一个稳定的库,仍然可以与最新版本的Ruby一起使用。并非所有代码库都需要每天更新,以免被视为“死胡同”。
bigtunacan


-1

简单的解决方案:

days90_ago = 90.days.ago.to_date.to_s

OUTPUT:
puts 90_days_ago
=> "2019-10-09" # considering cur_date: 2020-01-07

这是使用ActiveSupport(Rails)。
Espen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.